1 #include "vctrs.h"
2 #include "utils.h"
3 #include "type-data-frame.h"
4 #include "owned.h"
5
6 #include <R_ext/Rdynload.h>
7
8 // Initialised at load time
9 bool (*rlang_is_splice_box)(SEXP) = NULL;
10 SEXP (*rlang_unbox)(SEXP) = NULL;
11 SEXP (*rlang_env_dots_values)(SEXP) = NULL;
12 SEXP (*rlang_env_dots_list)(SEXP) = NULL;
13 SEXP vctrs_method_table = NULL;
14 SEXP base_method_table = NULL;
15 SEXP s4_c_method_table = NULL;
16
17 SEXP strings_tbl = NULL;
18 SEXP strings_tbl_df = NULL;
19 SEXP strings_data_frame = NULL;
20 SEXP strings_date = NULL;
21 SEXP strings_posixct = NULL;
22 SEXP strings_posixlt = NULL;
23 SEXP strings_posixt = NULL;
24 SEXP strings_factor = NULL;
25 SEXP strings_ordered = NULL;
26 SEXP strings_list = NULL;
27
28 SEXP classes_data_frame = NULL;
29 SEXP classes_factor = NULL;
30 SEXP classes_ordered = NULL;
31 SEXP classes_date = NULL;
32 SEXP classes_posixct = NULL;
33 SEXP classes_tibble = NULL;
34 SEXP classes_vctrs_group_rle = NULL;
35
36 static SEXP syms_as_data_frame2 = NULL;
37 static SEXP fns_as_data_frame2 = NULL;
38
39
40 static SEXP vctrs_eval_mask_n_impl(SEXP fn_sym, SEXP fn, SEXP* syms, SEXP* args, SEXP mask);
41
42 /**
43 * Evaluate with masked arguments
44 *
45 * This takes two arrays of argument (`args`) and argument names
46 * `syms`). The names should correspond to formal arguments of `fn`.
47 * Elements of `args` are assigned to their corresponding name in
48 * `syms` directly in the current environment, i.e. the environment of
49 * the closure wrapping the `.Call()` invokation. Since masked
50 * evaluation causes side effects and variable assignments in that
51 * frame environment, the native code invokation must be tailing: no
52 * further R code (including `on.exit()` expressions) should be
53 * evaluated in that closure wrapper.
54 *
55 * A call to `fn` is constructed with the
56 * CARs and TAGs assigned symmetrically to the elements of
57 * `syms`. This way the arguments are masked by symbols corresponding
58 * to the formal parameters.
59 *
60 * @param fn The function to call.
61 * @param syms A null-terminated array of symbols. The arguments
62 * `args` are assigned to these symbols. The assignment occurs in a
63 * child of `env` and the dispatch call refers to these symbols.
64 * @param args A null-terminated array of arguments passed to the method.
65 * @param env The environment in which to evaluate.
66 */
vctrs_eval_mask_n(SEXP fn,SEXP * syms,SEXP * args)67 SEXP vctrs_eval_mask_n(SEXP fn, SEXP* syms, SEXP* args) {
68 SEXP mask = PROTECT(r_peek_frame());
69 SEXP out = vctrs_eval_mask_n_impl(R_NilValue, fn, syms, args, mask);
70
71 UNPROTECT(1);
72 return out;
73 }
vctrs_eval_mask1(SEXP fn,SEXP x_sym,SEXP x)74 SEXP vctrs_eval_mask1(SEXP fn,
75 SEXP x_sym, SEXP x) {
76 SEXP syms[2] = { x_sym, NULL };
77 SEXP args[2] = { x, NULL };
78 return vctrs_eval_mask_n(fn, syms, args);
79 }
vctrs_eval_mask2(SEXP fn,SEXP x_sym,SEXP x,SEXP y_sym,SEXP y)80 SEXP vctrs_eval_mask2(SEXP fn,
81 SEXP x_sym, SEXP x,
82 SEXP y_sym, SEXP y) {
83 SEXP syms[3] = { x_sym, y_sym, NULL };
84 SEXP args[3] = { x, y, NULL };
85 return vctrs_eval_mask_n(fn, syms, args);
86 }
vctrs_eval_mask3(SEXP fn,SEXP x_sym,SEXP x,SEXP y_sym,SEXP y,SEXP z_sym,SEXP z)87 SEXP vctrs_eval_mask3(SEXP fn,
88 SEXP x_sym, SEXP x,
89 SEXP y_sym, SEXP y,
90 SEXP z_sym, SEXP z) {
91 SEXP syms[4] = { x_sym, y_sym, z_sym, NULL };
92 SEXP args[4] = { x, y, z, NULL };
93 return vctrs_eval_mask_n(fn, syms, args);
94 }
vctrs_eval_mask4(SEXP fn,SEXP x1_sym,SEXP x1,SEXP x2_sym,SEXP x2,SEXP x3_sym,SEXP x3,SEXP x4_sym,SEXP x4)95 SEXP vctrs_eval_mask4(SEXP fn,
96 SEXP x1_sym, SEXP x1,
97 SEXP x2_sym, SEXP x2,
98 SEXP x3_sym, SEXP x3,
99 SEXP x4_sym, SEXP x4) {
100 SEXP syms[5] = { x1_sym, x2_sym, x3_sym, x4_sym, NULL };
101 SEXP args[5] = { x1, x2, x3, x4, NULL };
102 return vctrs_eval_mask_n(fn, syms, args);
103 }
vctrs_eval_mask5(SEXP fn,SEXP x1_sym,SEXP x1,SEXP x2_sym,SEXP x2,SEXP x3_sym,SEXP x3,SEXP x4_sym,SEXP x4,SEXP x5_sym,SEXP x5)104 SEXP vctrs_eval_mask5(SEXP fn,
105 SEXP x1_sym, SEXP x1,
106 SEXP x2_sym, SEXP x2,
107 SEXP x3_sym, SEXP x3,
108 SEXP x4_sym, SEXP x4,
109 SEXP x5_sym, SEXP x5) {
110 SEXP syms[6] = { x1_sym, x2_sym, x3_sym, x4_sym, x5_sym, NULL };
111 SEXP args[6] = { x1, x2, x3, x4, x5, NULL };
112 return vctrs_eval_mask_n(fn, syms, args);
113 }
vctrs_eval_mask6(SEXP fn,SEXP x1_sym,SEXP x1,SEXP x2_sym,SEXP x2,SEXP x3_sym,SEXP x3,SEXP x4_sym,SEXP x4,SEXP x5_sym,SEXP x5,SEXP x6_sym,SEXP x6)114 SEXP vctrs_eval_mask6(SEXP fn,
115 SEXP x1_sym, SEXP x1,
116 SEXP x2_sym, SEXP x2,
117 SEXP x3_sym, SEXP x3,
118 SEXP x4_sym, SEXP x4,
119 SEXP x5_sym, SEXP x5,
120 SEXP x6_sym, SEXP x6) {
121 SEXP syms[7] = { x1_sym, x2_sym, x3_sym, x4_sym, x5_sym, x6_sym, NULL };
122 SEXP args[7] = { x1, x2, x3, x4, x5, x6, NULL };
123 return vctrs_eval_mask_n(fn, syms, args);
124 }
vctrs_eval_mask7(SEXP fn,SEXP x1_sym,SEXP x1,SEXP x2_sym,SEXP x2,SEXP x3_sym,SEXP x3,SEXP x4_sym,SEXP x4,SEXP x5_sym,SEXP x5,SEXP x6_sym,SEXP x6,SEXP x7_sym,SEXP x7)125 SEXP vctrs_eval_mask7(SEXP fn,
126 SEXP x1_sym, SEXP x1,
127 SEXP x2_sym, SEXP x2,
128 SEXP x3_sym, SEXP x3,
129 SEXP x4_sym, SEXP x4,
130 SEXP x5_sym, SEXP x5,
131 SEXP x6_sym, SEXP x6,
132 SEXP x7_sym, SEXP x7) {
133 SEXP syms[8] = { x1_sym, x2_sym, x3_sym, x4_sym, x5_sym, x6_sym, x7_sym, NULL };
134 SEXP args[8] = { x1, x2, x3, x4, x5, x6, x7, NULL };
135 return vctrs_eval_mask_n(fn, syms, args);
136 }
137
138 /**
139 * Dispatch in the current environment
140 *
141 * Like `vctrs_eval_mask_n()`, the arguments `args` are are assigned
142 * to the symbols `syms`. In addition, the function `fn` is assigned
143 * to `fn_sym`. The mask is the current environment which has hygiene
144 * implications regarding the closure wrapping `.Call()`, as
145 * documented in `vctrs_eval_mask_n()`.
146 *
147 * @param fn_sym A symbol to which `fn` is assigned.
148 * @inheritParams vctrs_eval_mask_n
149 */
vctrs_dispatch_n(SEXP fn_sym,SEXP fn,SEXP * syms,SEXP * args)150 SEXP vctrs_dispatch_n(SEXP fn_sym, SEXP fn, SEXP* syms, SEXP* args) {
151 SEXP mask = PROTECT(r_peek_frame());
152
153 SEXP out = vctrs_eval_mask_n_impl(fn_sym, fn, syms, args, mask);
154
155 UNPROTECT(1);
156 return out;
157 }
vctrs_dispatch1(SEXP fn_sym,SEXP fn,SEXP x_sym,SEXP x)158 SEXP vctrs_dispatch1(SEXP fn_sym, SEXP fn,
159 SEXP x_sym, SEXP x) {
160 SEXP syms[2] = { x_sym, NULL };
161 SEXP args[2] = { x, NULL };
162 return vctrs_dispatch_n(fn_sym, fn, syms, args);
163 }
vctrs_dispatch2(SEXP fn_sym,SEXP fn,SEXP x_sym,SEXP x,SEXP y_sym,SEXP y)164 SEXP vctrs_dispatch2(SEXP fn_sym, SEXP fn,
165 SEXP x_sym, SEXP x,
166 SEXP y_sym, SEXP y) {
167 SEXP syms[3] = { x_sym, y_sym, NULL };
168 SEXP args[3] = { x, y, NULL };
169 return vctrs_dispatch_n(fn_sym, fn, syms, args);
170 }
vctrs_dispatch3(SEXP fn_sym,SEXP fn,SEXP x_sym,SEXP x,SEXP y_sym,SEXP y,SEXP z_sym,SEXP z)171 SEXP vctrs_dispatch3(SEXP fn_sym, SEXP fn,
172 SEXP x_sym, SEXP x,
173 SEXP y_sym, SEXP y,
174 SEXP z_sym, SEXP z) {
175 SEXP syms[4] = { x_sym, y_sym, z_sym, NULL };
176 SEXP args[4] = { x, y, z, NULL };
177 return vctrs_dispatch_n(fn_sym, fn, syms, args);
178 }
vctrs_dispatch4(SEXP fn_sym,SEXP fn,SEXP w_sym,SEXP w,SEXP x_sym,SEXP x,SEXP y_sym,SEXP y,SEXP z_sym,SEXP z)179 SEXP vctrs_dispatch4(SEXP fn_sym, SEXP fn,
180 SEXP w_sym, SEXP w,
181 SEXP x_sym, SEXP x,
182 SEXP y_sym, SEXP y,
183 SEXP z_sym, SEXP z) {
184 SEXP syms[5] = { w_sym, x_sym, y_sym, z_sym, NULL };
185 SEXP args[5] = { w, x, y, z, NULL };
186 return vctrs_dispatch_n(fn_sym, fn, syms, args);
187 }
vctrs_dispatch6(SEXP fn_sym,SEXP fn,SEXP x1_sym,SEXP x1,SEXP x2_sym,SEXP x2,SEXP x3_sym,SEXP x3,SEXP x4_sym,SEXP x4,SEXP x5_sym,SEXP x5,SEXP x6_sym,SEXP x6)188 SEXP vctrs_dispatch6(SEXP fn_sym, SEXP fn,
189 SEXP x1_sym, SEXP x1,
190 SEXP x2_sym, SEXP x2,
191 SEXP x3_sym, SEXP x3,
192 SEXP x4_sym, SEXP x4,
193 SEXP x5_sym, SEXP x5,
194 SEXP x6_sym, SEXP x6) {
195 SEXP syms[7] = { x1_sym, x2_sym, x3_sym, x4_sym, x5_sym, x6_sym, NULL };
196 SEXP args[7] = { x1, x2, x3, x4, x5, x6, NULL };
197 return vctrs_dispatch_n(fn_sym, fn, syms, args);
198 }
199
vctrs_eval_mask_n_impl(SEXP fn_sym,SEXP fn,SEXP * syms,SEXP * args,SEXP env)200 static SEXP vctrs_eval_mask_n_impl(SEXP fn_sym, SEXP fn, SEXP* syms, SEXP* args, SEXP env) {
201 SEXP mask = PROTECT(r_new_environment(env));
202
203 if (fn_sym != R_NilValue) {
204 Rf_defineVar(fn_sym, fn, mask);
205 fn = fn_sym;
206 }
207
208 SEXP body = PROTECT(r_call(fn, syms, syms));
209 SEXP call_fn = PROTECT(r_new_function(R_NilValue, body, mask));
210 SEXP call = PROTECT(Rf_lang1(call_fn));
211
212 while (*syms) {
213 Rf_defineVar(*syms, *args, mask);
214 ++syms; ++args;
215 }
216
217 SEXP out = Rf_eval(call, env);
218
219 UNPROTECT(4);
220 return out;
221 }
222
223 // [[ register() ]]
vctrs_maybe_shared_col(SEXP x,SEXP i)224 SEXP vctrs_maybe_shared_col(SEXP x, SEXP i) {
225 int i_ = r_int_get(i, 0) - 1;
226 SEXP col = VECTOR_ELT(x, i_);
227 bool out = MAYBE_SHARED(col);
228 return Rf_ScalarLogical(out);
229 }
230
231 // [[ register() ]]
vctrs_new_df_unshared_col()232 SEXP vctrs_new_df_unshared_col() {
233 SEXP col = PROTECT(Rf_allocVector(INTSXP, 1));
234 INTEGER(col)[0] = 1;
235
236 SEXP out = PROTECT(Rf_allocVector(VECSXP, 1));
237
238 // In R 4.0.0, `SET_VECTOR_ELT()` bumps the REFCNT of
239 // `col`. Because of this, `col` is now referenced (refcnt > 0),
240 // but it isn't shared (refcnt > 1).
241 SET_VECTOR_ELT(out, 0, col);
242
243 SEXP names = PROTECT(Rf_allocVector(STRSXP, 1));
244 SET_STRING_ELT(names, 0, Rf_mkChar("x"));
245
246 Rf_setAttrib(out, R_NamesSymbol, names);
247
248 init_data_frame(out, 1);
249
250 UNPROTECT(3);
251 return out;
252 }
253
254 // An alternative to `attributes(x) <- attrib`, which makes
255 // two copies on R < 3.6.0
256 // [[ register() ]]
vctrs_set_attributes(SEXP x,SEXP attrib)257 SEXP vctrs_set_attributes(SEXP x, SEXP attrib) {
258 R_len_t n_attrib = Rf_length(attrib);
259 int n_protect = 0;
260
261 x = PROTECT(r_clone_referenced(x));
262 ++n_protect;
263
264 // Remove existing attributes, and unset the object bit
265 SET_ATTRIB(x, R_NilValue);
266 SET_OBJECT(x, 0);
267
268 // Possible early exit after removing attributes
269 if (n_attrib == 0) {
270 UNPROTECT(n_protect);
271 return x;
272 }
273
274 SEXP names = Rf_getAttrib(attrib, R_NamesSymbol);
275
276 if (Rf_isNull(names)) {
277 Rf_errorcall(R_NilValue, "Attributes must be named.");
278 }
279
280 // Check that each element of `names` is named.
281 for (R_len_t i = 0; i < n_attrib; ++i) {
282 SEXP name = STRING_ELT(names, i);
283
284 if (name == NA_STRING || name == R_BlankString) {
285 const char* msg = "All attributes must have names. Attribute %i does not.";
286 Rf_errorcall(R_NilValue, msg, i + 1);
287 }
288 }
289
290 // Always set `dim` first, if it exists. This way it is set before `dimnames`.
291 int dim_pos = -1;
292 for (R_len_t i = 0; i < n_attrib; ++i) {
293 if (!strcmp(CHAR(STRING_ELT(names, i)), "dim")) {
294 dim_pos = i;
295 break;
296 }
297 }
298
299 if (dim_pos != -1) {
300 Rf_setAttrib(x, R_DimSymbol, VECTOR_ELT(attrib, dim_pos));
301 }
302
303 for (R_len_t i = 0; i < n_attrib; ++i) {
304 if (i == dim_pos) {
305 continue;
306 }
307 Rf_setAttrib(x, Rf_installChar(STRING_ELT(names, i)), VECTOR_ELT(attrib, i));
308 }
309
310 UNPROTECT(n_protect);
311 return x;
312 }
313
314 // [[ include("utils.h") ]]
map(SEXP x,SEXP (* fn)(SEXP))315 SEXP map(SEXP x, SEXP (*fn)(SEXP)) {
316 R_len_t n = Rf_length(x);
317 SEXP out = PROTECT(Rf_allocVector(VECSXP, n));
318
319 for (R_len_t i = 0; i < n; ++i) {
320 SET_VECTOR_ELT(out, i, fn(VECTOR_ELT(x, i)));
321 }
322
323 SEXP nms = PROTECT(Rf_getAttrib(x, R_NamesSymbol));
324 Rf_setAttrib(out, R_NamesSymbol, nms);
325
326 UNPROTECT(2);
327 return out;
328 }
329 // [[ include("utils.h") ]]
map_with_data(SEXP x,SEXP (* fn)(SEXP,void *),void * data)330 SEXP map_with_data(SEXP x, SEXP (*fn)(SEXP, void*), void* data) {
331 R_len_t n = Rf_length(x);
332 SEXP out = PROTECT(Rf_allocVector(VECSXP, n));
333
334 for (R_len_t i = 0; i < n; ++i) {
335 SET_VECTOR_ELT(out, i, fn(VECTOR_ELT(x, i), data));
336 }
337
338 SEXP nms = PROTECT(Rf_getAttrib(x, R_NamesSymbol));
339 Rf_setAttrib(out, R_NamesSymbol, nms);
340
341 UNPROTECT(2);
342 return out;
343 }
344
345 // [[ include("utils.h") ]]
bare_df_map(SEXP df,SEXP (* fn)(SEXP))346 SEXP bare_df_map(SEXP df, SEXP (*fn)(SEXP)) {
347 SEXP out = PROTECT(map(df, fn));
348
349 // Total ownership because `map()` generates a fresh list
350 out = vec_bare_df_restore(out, df, vctrs_shared_zero_int, VCTRS_OWNED_true);
351
352 UNPROTECT(1);
353 return out;
354 }
355
356 // [[ include("utils.h") ]]
df_map(SEXP df,SEXP (* fn)(SEXP))357 SEXP df_map(SEXP df, SEXP (*fn)(SEXP)) {
358 SEXP out = PROTECT(map(df, fn));
359
360 // Total ownership because `map()` generates a fresh list
361 out = vec_df_restore(out, df, vctrs_shared_zero_int, VCTRS_OWNED_true);
362
363 UNPROTECT(1);
364 return out;
365 }
366
367 #define RESIZE(CONST_DEREF, DEREF, CTYPE, SEXPTYPE) do { \
368 if (x_size == size) { \
369 return x; \
370 } \
371 \
372 const CTYPE* p_x = CONST_DEREF(x); \
373 \
374 SEXP out = PROTECT(Rf_allocVector(SEXPTYPE, size)); \
375 CTYPE* p_out = DEREF(out); \
376 \
377 r_ssize copy_size = (size > x_size) ? x_size : size; \
378 \
379 memcpy(p_out, p_x, copy_size * sizeof(CTYPE)); \
380 \
381 UNPROTECT(1); \
382 return out; \
383 } while (0)
384
385 #define RESIZE_BARRIER(CONST_DEREF, SEXPTYPE, SET) do { \
386 if (x_size == size) { \
387 return x; \
388 } \
389 \
390 const SEXP* p_x = CONST_DEREF(x); \
391 \
392 SEXP out = PROTECT(Rf_allocVector(SEXPTYPE, size)); \
393 \
394 r_ssize copy_size = (size > x_size) ? x_size : size; \
395 \
396 for (r_ssize i = 0; i < copy_size; ++i) { \
397 SET(out, i, p_x[i]); \
398 } \
399 \
400 UNPROTECT(1); \
401 return out; \
402 } while (0)
403
404 // Faster than `Rf_xlengthgets()` because that fills the new extended
405 // locations with `NA`, which we don't need.
406 // [[ include("utils.h") ]]
int_resize(SEXP x,r_ssize x_size,r_ssize size)407 SEXP int_resize(SEXP x, r_ssize x_size, r_ssize size) {
408 RESIZE(INTEGER_RO, INTEGER, int, INTSXP);
409 }
410 // [[ include("utils.h") ]]
raw_resize(SEXP x,r_ssize x_size,r_ssize size)411 SEXP raw_resize(SEXP x, r_ssize x_size, r_ssize size) {
412 RESIZE(RAW_RO, RAW, Rbyte, RAWSXP);
413 }
414 // [[ include("utils.h") ]]
chr_resize(SEXP x,r_ssize x_size,r_ssize size)415 SEXP chr_resize(SEXP x, r_ssize x_size, r_ssize size) {
416 RESIZE_BARRIER(STRING_PTR_RO, STRSXP, SET_STRING_ELT);
417 }
418
419 #undef RESIZE
420 #undef RESIZE_BARRIER
421
422
never_reached(const char * fn)423 inline void never_reached(const char* fn) {
424 Rf_error("Internal error in `%s()`: Reached the unreachable.", fn);
425 }
426
427
428 static char s3_buf[200];
429
s3_paste_method_sym(const char * generic,const char * class)430 SEXP s3_paste_method_sym(const char* generic, const char* class) {
431 int gen_len = strlen(generic);
432 int class_len = strlen(class);
433 int dot_len = 1;
434 if (gen_len + class_len + dot_len >= sizeof(s3_buf)) {
435 stop_internal("s3_paste_method_sym", "Generic or class name is too long.");
436 }
437
438 char* buf = s3_buf;
439
440 memcpy(buf, generic, gen_len); buf += gen_len;
441 *buf = '.'; ++buf;
442 memcpy(buf, class, class_len); buf += class_len;
443 *buf = '\0';
444
445 return Rf_install(s3_buf);
446 }
447
448 // First check in global env, then in method table
s3_get_method(const char * generic,const char * class,SEXP table)449 SEXP s3_get_method(const char* generic, const char* class, SEXP table) {
450 SEXP sym = s3_paste_method_sym(generic, class);
451 return s3_sym_get_method(sym, table);
452 }
s3_sym_get_method(SEXP sym,SEXP table)453 SEXP s3_sym_get_method(SEXP sym, SEXP table) {
454 SEXP method = r_env_get(R_GlobalEnv, sym);
455 if (r_is_function(method)) {
456 return method;
457 }
458
459 method = r_env_get(table, sym);
460 if (r_is_function(method)) {
461 return method;
462 }
463
464 return R_NilValue;
465 }
466
467 // [[ register() ]]
vctrs_s3_find_method(SEXP generic,SEXP x,SEXP table)468 SEXP vctrs_s3_find_method(SEXP generic, SEXP x, SEXP table) {
469 return s3_find_method(r_chr_get_c_string(generic, 0), x, table);
470 }
471
472 // [[ include("utils.h") ]]
s3_find_method(const char * generic,SEXP x,SEXP table)473 SEXP s3_find_method(const char* generic, SEXP x, SEXP table) {
474 if (!OBJECT(x)) {
475 return R_NilValue;
476 }
477
478 SEXP class = PROTECT(Rf_getAttrib(x, R_ClassSymbol));
479 SEXP method = s3_class_find_method(generic, class, table);
480
481 UNPROTECT(1);
482 return method;
483 }
484
485 // [[ include("utils.h") ]]
s3_class_find_method(const char * generic,SEXP class,SEXP table)486 SEXP s3_class_find_method(const char* generic, SEXP class, SEXP table) {
487 // Avoid corrupt objects where `x` is an OBJECT(), but the class is NULL
488 if (class == R_NilValue) {
489 return R_NilValue;
490 }
491
492 SEXP const* p_class = STRING_PTR_RO(class);
493 int n_class = Rf_length(class);
494
495 for (int i = 0; i < n_class; ++i) {
496 SEXP method = s3_get_method(generic, CHAR(p_class[i]), table);
497 if (method != R_NilValue) {
498 return method;
499 }
500 }
501
502 return R_NilValue;
503 }
504
505 // [[ include("utils.h") ]]
s3_get_class(SEXP x)506 SEXP s3_get_class(SEXP x) {
507 SEXP class = R_NilValue;
508
509 if (OBJECT(x)) {
510 class = Rf_getAttrib(x, R_ClassSymbol);
511 }
512
513 // This handles unclassed objects as well as gremlins objects where
514 // `x` is an OBJECT(), but the class is NULL
515 if (class == R_NilValue) {
516 class = s3_bare_class(x);
517 }
518
519 if (!Rf_length(class)) {
520 stop_internal("s3_get_class", "Class must have length.");
521 }
522
523 return class;
524 }
525
s3_get_class0(SEXP x)526 SEXP s3_get_class0(SEXP x) {
527 SEXP class = PROTECT(s3_get_class(x));
528 SEXP out = STRING_ELT(class, 0);
529 UNPROTECT(1);
530 return out;
531 }
532
533 // [[ include("utils.h") ]]
s3_find_method_xy(const char * generic,SEXP x,SEXP y,SEXP table,SEXP * method_sym_out)534 SEXP s3_find_method_xy(const char* generic,
535 SEXP x,
536 SEXP y,
537 SEXP table,
538 SEXP* method_sym_out) {
539 SEXP x_class = PROTECT(s3_get_class0(x));
540 SEXP y_class = PROTECT(s3_get_class0(y));
541
542 SEXP method_sym = R_NilValue;
543 method_sym = s3_paste_method_sym(generic, CHAR(x_class));
544 method_sym = s3_paste_method_sym(CHAR(PRINTNAME(method_sym)), CHAR(y_class));
545
546 SEXP method = s3_sym_get_method(method_sym, table);
547
548 if (method == R_NilValue) {
549 *method_sym_out = R_NilValue;
550 } else {
551 *method_sym_out = method_sym;
552 }
553
554 UNPROTECT(2);
555 return method;
556 }
557
558 // [[ include("utils.h") ]]
s3_find_method2(const char * generic,SEXP x,SEXP table,SEXP * method_sym_out)559 SEXP s3_find_method2(const char* generic,
560 SEXP x,
561 SEXP table,
562 SEXP* method_sym_out) {
563 SEXP class = PROTECT(s3_get_class0(x));
564
565 SEXP method_sym = s3_paste_method_sym(generic, CHAR(class));
566 SEXP method = s3_sym_get_method(method_sym, table);
567
568 if (method == R_NilValue) {
569 *method_sym_out = R_NilValue;
570 } else {
571 *method_sym_out = method_sym;
572 }
573
574 UNPROTECT(1);
575 return method;
576 }
577
578
579 // [[ include("utils.h") ]]
s3_bare_class(SEXP x)580 SEXP s3_bare_class(SEXP x) {
581 switch (TYPEOF(x)) {
582 case NILSXP: return chrs_null;
583 case LGLSXP: return chrs_logical;
584 case INTSXP: return chrs_integer;
585 case REALSXP: return chrs_double;
586 case CPLXSXP: return chrs_complex;
587 case STRSXP: return chrs_character;
588 case RAWSXP: return chrs_raw;
589 case VECSXP: return chrs_list;
590 case EXPRSXP: return chrs_expression;
591 case CLOSXP:
592 case SPECIALSXP:
593 case BUILTINSXP: return chrs_function;
594 default: stop_unimplemented_vctrs_type("base_dispatch_class_str", vec_typeof(x));
595 }
596 }
597
s4_get_method(const char * class,SEXP table)598 static SEXP s4_get_method(const char* class, SEXP table) {
599 SEXP sym = Rf_install(class);
600
601 SEXP method = r_env_get(table, sym);
602 if (r_is_function(method)) {
603 return method;
604 }
605
606 return R_NilValue;
607 }
608
609 // For S4 objects, the `table` is specific to the generic
s4_find_method(SEXP x,SEXP table)610 SEXP s4_find_method(SEXP x, SEXP table) {
611 if (!IS_S4_OBJECT(x)) {
612 return R_NilValue;
613 }
614
615 SEXP class = PROTECT(Rf_getAttrib(x, R_ClassSymbol));
616 SEXP out = s4_class_find_method(class, table);
617
618 UNPROTECT(1);
619 return out;
620 }
s4_class_find_method(SEXP class,SEXP table)621 SEXP s4_class_find_method(SEXP class, SEXP table) {
622 // Avoid corrupt objects where `x` is an OBJECT(), but the class is NULL
623 if (class == R_NilValue) {
624 return R_NilValue;
625 }
626
627 SEXP const* p_class = STRING_PTR_RO(class);
628 int n_class = Rf_length(class);
629
630 for (int i = 0; i < n_class; ++i) {
631 SEXP method = s4_get_method(CHAR(p_class[i]), table);
632 if (method != R_NilValue) {
633 return method;
634 }
635 }
636
637 return R_NilValue;
638 }
639
640 // [[ include("utils.h") ]]
vec_implements_ptype2(SEXP x)641 bool vec_implements_ptype2(SEXP x) {
642 switch (vec_typeof(x)) {
643 case vctrs_type_scalar:
644 return false;
645 case vctrs_type_s3: {
646 SEXP method_sym = R_NilValue;
647 SEXP method = s3_find_method_xy("vec_ptype2", x, x, vctrs_method_table, &method_sym);
648
649 if (method != R_NilValue) {
650 return true;
651 }
652
653 method = s3_find_method2("vec_ptype2", x, vctrs_method_table, &method_sym);
654 return method != R_NilValue;
655 }
656 default:
657 return true;
658 }
659 }
660
661 // [[ register() ]]
vctrs_implements_ptype2(SEXP x)662 SEXP vctrs_implements_ptype2(SEXP x) {
663 return r_lgl(vec_implements_ptype2(x));
664 }
665
666 // [[ include("utils.h") ]]
list_first_non_null(SEXP xs,R_len_t * non_null_i)667 SEXP list_first_non_null(SEXP xs, R_len_t* non_null_i) {
668 SEXP x = R_NilValue;
669 R_len_t n = Rf_length(xs);
670
671 R_len_t i = 0;
672 for (; i < n; ++i) {
673 x = VECTOR_ELT(xs, i);
674 if (x != R_NilValue) {
675 break;
676 }
677 }
678
679 if (non_null_i) {
680 *non_null_i = i;
681 }
682 return x;
683 }
684
685 // [[ include("utils.h") ]]
list_is_homogeneously_classed(SEXP xs)686 bool list_is_homogeneously_classed(SEXP xs) {
687 R_len_t n = Rf_length(xs);
688 if (n == 0 || n == 1) {
689 return true;
690 }
691
692 R_len_t i = -1;
693 SEXP first = list_first_non_null(xs, &i);
694 SEXP first_class = PROTECT(r_class(first));
695
696 for (; i < n; ++i) {
697 SEXP this = VECTOR_ELT(xs, i);
698 if (this == R_NilValue) {
699 continue;
700 }
701 SEXP this_class = PROTECT(r_class(this));
702
703 if (!equal_object(first_class, this_class)) {
704 UNPROTECT(2);
705 return false;
706 }
707
708 UNPROTECT(1);
709 }
710
711 UNPROTECT(1);
712 return true;
713 }
714
715 // [[ include("utils.h") ]]
node_compact_d(SEXP node)716 SEXP node_compact_d(SEXP node) {
717 SEXP handle = PROTECT(Rf_cons(R_NilValue, node));
718
719 SEXP prev = handle;
720 while (node != R_NilValue) {
721 if (CAR(node) == R_NilValue) {
722 SETCDR(prev, CDR(node));
723 } else {
724 prev = node;
725 }
726 node = CDR(node);
727 }
728
729 UNPROTECT(1);
730 return CDR(handle);
731 }
732
733
734 // [[ include("utils.h") ]]
new_empty_factor(SEXP levels)735 SEXP new_empty_factor(SEXP levels) {
736 if (TYPEOF(levels) != STRSXP) {
737 stop_internal("new_empty_factor", "`level` must be a character vector.");
738 }
739
740 SEXP out = PROTECT(Rf_allocVector(INTSXP, 0));
741
742 Rf_setAttrib(out, R_LevelsSymbol, levels);
743 Rf_setAttrib(out, R_ClassSymbol, classes_factor);
744
745 UNPROTECT(1);
746 return out;
747 }
748
749 // [[ include("utils.h") ]]
new_empty_ordered(SEXP levels)750 SEXP new_empty_ordered(SEXP levels) {
751 SEXP out = PROTECT(Rf_allocVector(INTSXP, 0));
752
753 Rf_setAttrib(out, R_LevelsSymbol, levels);
754 Rf_setAttrib(out, R_ClassSymbol, classes_ordered);
755
756 UNPROTECT(1);
757 return out;
758 }
759
760 // [[ include("utils.h") ]]
list_has_inner_vec_names(SEXP x,R_len_t size)761 bool list_has_inner_vec_names(SEXP x, R_len_t size) {
762 for (R_len_t i = 0; i < size; ++i) {
763 SEXP elt = VECTOR_ELT(x, i);
764 if (vec_names(elt) != R_NilValue) {
765 return true;
766 }
767 }
768
769 return false;
770 }
771
772 /**
773 * Pluck elements `i` from a list of lists.
774 * @return A list of the same length as `xs`.
775 */
776 // [[ include("utils.h") ]]
list_pluck(SEXP xs,R_len_t i)777 SEXP list_pluck(SEXP xs, R_len_t i) {
778 R_len_t n = Rf_length(xs);
779 SEXP out = PROTECT(r_new_list(n));
780
781 for (R_len_t j = 0; j < n; ++j) {
782 SEXP x = r_list_get(xs, j);
783 r_list_poke(out, j, r_list_get(x, i));
784 }
785
786 UNPROTECT(1);
787 return out;
788 }
789
790
791 // [[ include("vctrs.h") ]]
dbl_classify(double x)792 enum vctrs_dbl_class dbl_classify(double x) {
793 if (!isnan(x)) {
794 return vctrs_dbl_number;
795 }
796
797 union vctrs_dbl_indicator indicator;
798 indicator.value = x;
799
800 if (indicator.key[vctrs_indicator_pos] == 1954) {
801 return vctrs_dbl_missing;
802 } else {
803 return vctrs_dbl_nan;
804 }
805 }
806
807 // Initialised at load time
808 SEXP compact_seq_attrib = NULL;
809
810 // p[0] = Start value
811 // p[1] = Sequence size. Always >= 1.
812 // p[2] = Step size to increment/decrement `start` with
init_compact_seq(int * p,R_len_t start,R_len_t size,bool increasing)813 void init_compact_seq(int* p, R_len_t start, R_len_t size, bool increasing) {
814 int step = increasing ? 1 : -1;
815
816 p[0] = start;
817 p[1] = size;
818 p[2] = step;
819 }
820
821 // Returns a compact sequence that `vec_slice()` understands
822 // The sequence is generally generated as `[start, start +/- size)`
823 // If `size == 0` a 0-length sequence is generated
824 // `start` is 0-based
compact_seq(R_len_t start,R_len_t size,bool increasing)825 SEXP compact_seq(R_len_t start, R_len_t size, bool increasing) {
826 if (start < 0) {
827 stop_internal("compact_seq", "`start` must not be negative.");
828 }
829
830 if (size < 0) {
831 stop_internal("compact_seq", "`size` must not be negative.");
832 }
833
834 if (!increasing && size > start + 1) {
835 stop_internal("compact_seq", "`size` must not be larger than `start` for decreasing sequences.");
836 }
837
838 SEXP info = PROTECT(Rf_allocVector(INTSXP, 3));
839
840 int* p = INTEGER(info);
841 init_compact_seq(p, start, size, increasing);
842
843 SET_ATTRIB(info, compact_seq_attrib);
844
845 UNPROTECT(1);
846 return info;
847 }
848
is_compact_seq(SEXP x)849 bool is_compact_seq(SEXP x) {
850 return ATTRIB(x) == compact_seq_attrib;
851 }
852
853 // Materialize a 1-based sequence
compact_seq_materialize(SEXP x)854 SEXP compact_seq_materialize(SEXP x) {
855 int* p = INTEGER(x);
856 R_len_t start = p[0] + 1;
857 R_len_t size = p[1];
858 R_len_t step = p[2];
859
860 SEXP out = PROTECT(Rf_allocVector(INTSXP, size));
861 int* out_data = INTEGER(out);
862
863 for (R_len_t i = 0; i < size; ++i, ++out_data, start += step) {
864 *out_data = start;
865 }
866
867 UNPROTECT(1);
868 return out;
869 }
870
871 // Initialised at load time
872 SEXP compact_rep_attrib = NULL;
873
init_compact_rep(int * p,R_len_t i,R_len_t n)874 void init_compact_rep(int* p, R_len_t i, R_len_t n) {
875 p[0] = i;
876 p[1] = n;
877 }
878
879 // Returns a compact repetition that `vec_slice()` understands
880 // `i` should be an R-based index
compact_rep(R_len_t i,R_len_t n)881 SEXP compact_rep(R_len_t i, R_len_t n) {
882 if (n < 0) {
883 stop_internal("compact_rep", "Negative `n` in `compact_rep()`.");
884 }
885
886 SEXP rep = PROTECT(Rf_allocVector(INTSXP, 2));
887
888 int* p = INTEGER(rep);
889 init_compact_rep(p, i, n);
890
891 SET_ATTRIB(rep, compact_rep_attrib);
892
893 UNPROTECT(1);
894 return rep;
895 }
896
is_compact_rep(SEXP x)897 bool is_compact_rep(SEXP x) {
898 return ATTRIB(x) == compact_rep_attrib;
899 }
900
compact_rep_materialize(SEXP x)901 SEXP compact_rep_materialize(SEXP x) {
902 int i = r_int_get(x, 0);
903 int n = r_int_get(x, 1);
904
905 SEXP out = PROTECT(Rf_allocVector(INTSXP, n));
906 r_int_fill(out, i, n);
907
908 UNPROTECT(1);
909 return out;
910 }
911
is_compact(SEXP x)912 bool is_compact(SEXP x) {
913 return is_compact_rep(x) || is_compact_seq(x);
914 }
915
compact_materialize(SEXP x)916 SEXP compact_materialize(SEXP x) {
917 if (is_compact_rep(x)) {
918 return compact_rep_materialize(x);
919 } else if (is_compact_seq(x)) {
920 return compact_seq_materialize(x);
921 } else {
922 return x;
923 }
924 }
925
vec_subscript_size(SEXP x)926 R_len_t vec_subscript_size(SEXP x) {
927 if (is_compact_rep(x)) {
928 return r_int_get(x, 1);
929 } else if (is_compact_seq(x)) {
930 return r_int_get(x, 1);
931 } else {
932 return vec_size(x);
933 }
934 }
935
936 static SEXP syms_colnames = NULL;
937 static SEXP fns_colnames = NULL;
938
939 // [[ include("utils.h") ]]
colnames(SEXP x)940 SEXP colnames(SEXP x) {
941 return vctrs_dispatch1(syms_colnames, fns_colnames,
942 syms_x, x);
943 }
944
945 // [[ include("utils.h") ]]
is_integer64(SEXP x)946 bool is_integer64(SEXP x) {
947 return TYPEOF(x) == REALSXP && Rf_inherits(x, "integer64");
948 }
949
950 // [[ include("utils.h") ]]
lgl_any_na(SEXP x)951 bool lgl_any_na(SEXP x) {
952 R_xlen_t size = Rf_xlength(x);
953 const int* p_x = LOGICAL_RO(x);
954
955 for (R_xlen_t i = 0; i < size; ++i) {
956 if (p_x[i] == NA_LOGICAL) {
957 return true;
958 }
959 }
960
961 return false;
962 }
963
r_vec_deref(SEXP x)964 void* r_vec_deref(SEXP x) {
965 switch (TYPEOF(x)) {
966 case LGLSXP: return LOGICAL(x);
967 case INTSXP: return INTEGER(x);
968 case REALSXP: return REAL(x);
969 case CPLXSXP: return COMPLEX(x);
970 case RAWSXP: return RAW(x);
971 default: stop_unimplemented_type("r_vec_deref", TYPEOF(x));
972 }
973 }
974
r_vec_deref_const(SEXP x)975 const void* r_vec_deref_const(SEXP x) {
976 switch (TYPEOF(x)) {
977 case LGLSXP: return LOGICAL_RO(x);
978 case INTSXP: return INTEGER_RO(x);
979 case REALSXP: return REAL_RO(x);
980 case CPLXSXP: return COMPLEX_RO(x);
981 case STRSXP: return STRING_PTR_RO(x);
982 case RAWSXP: return RAW_RO(x);
983 case VECSXP: return VECTOR_PTR_RO(x);
984 default: stop_unimplemented_type("r_vec_deref_const", TYPEOF(x));
985 }
986 }
987
r_vec_deref_barrier(SEXP x)988 void* r_vec_deref_barrier(SEXP x) {
989 switch (TYPEOF(x)) {
990 case STRSXP:
991 case VECSXP:
992 return (void*) x;
993 default:
994 return r_vec_deref(x);
995 }
996 }
997
r_vec_deref_barrier_const(SEXP x)998 const void* r_vec_deref_barrier_const(SEXP x) {
999 switch (TYPEOF(x)) {
1000 case STRSXP:
1001 case VECSXP:
1002 return (const void*) x;
1003 default:
1004 return r_vec_deref_const(x);
1005 }
1006 }
1007
1008 #define FILL(CTYPE, DEST, DEST_I, SRC, SRC_I, N) \
1009 do { \
1010 CTYPE* p_dest = (CTYPE*) DEST; \
1011 p_dest += DEST_I; \
1012 CTYPE* end = p_dest + N; \
1013 CTYPE value = ((const CTYPE*) SRC)[SRC_I]; \
1014 \
1015 while (p_dest != end) { \
1016 *p_dest++ = value; \
1017 } \
1018 } while (false)
1019
1020 #define FILL_BARRIER(GET, SET, DEST, DEST_I, SRC, SRC_I, N) \
1021 do { \
1022 SEXP out = (SEXP) DEST; \
1023 SEXP value = GET((SEXP) SRC, SRC_I); \
1024 \
1025 for (r_ssize i = 0; i < N; ++i) { \
1026 SET(out, DEST_I + i, value); \
1027 } \
1028 } while (false)
1029
r_vec_fill(SEXPTYPE type,void * dest,r_ssize dest_i,const void * src,r_ssize src_i,r_ssize n)1030 void r_vec_fill(SEXPTYPE type,
1031 void* dest,
1032 r_ssize dest_i,
1033 const void* src,
1034 r_ssize src_i,
1035 r_ssize n) {
1036 switch (type) {
1037 case INTSXP: FILL(int, dest, dest_i, src, src_i, n); return;
1038 case STRSXP: FILL_BARRIER(STRING_ELT, SET_STRING_ELT, dest, dest_i, src, src_i, n); return;
1039 default: stop_unimplemented_type("r_vec_fill", type);
1040 }
1041 }
1042
1043 #undef FILL_BARRIER
1044 #undef FILL
1045
1046
r_lgl_sum(SEXP x,bool na_true)1047 r_ssize r_lgl_sum(SEXP x, bool na_true) {
1048 if (TYPEOF(x) != LGLSXP) {
1049 stop_internal("r_lgl_sum", "Expected logical vector.");
1050 }
1051
1052 r_ssize n = r_length(x);
1053 const int* p_x = LOGICAL(x);
1054
1055 // This can't overflow since `sum` is necessarily smaller or equal
1056 // to the vector length expressed in `r_ssize`.
1057 r_ssize sum = 0;
1058
1059 if (na_true) {
1060 for (r_ssize i = 0; i < n; ++i) {
1061 const int elt = p_x[i];
1062
1063 if (elt) {
1064 ++sum;
1065 }
1066 }
1067 } else {
1068 for (r_ssize i = 0; i < n; ++i) {
1069 const int elt = p_x[i];
1070
1071 if (elt == 1) {
1072 ++sum;
1073 }
1074 }
1075 }
1076
1077 return sum;
1078 }
1079
r_lgl_which(SEXP x,bool na_propagate)1080 SEXP r_lgl_which(SEXP x, bool na_propagate) {
1081 if (TYPEOF(x) != LGLSXP) {
1082 stop_internal("r_lgl_which", "Expected logical vector.");
1083 }
1084
1085 r_ssize n = r_length(x);
1086 const int* p_x = LOGICAL(x);
1087
1088 r_ssize out_n = r_lgl_sum(x, na_propagate);
1089 SEXP out = PROTECT(Rf_allocVector(INTSXP, out_n));
1090 int* p_out = INTEGER(out);
1091 r_ssize loc = 0;
1092
1093 if (na_propagate) {
1094 for (r_ssize i = 0; i < n; ++i) {
1095 const int elt = p_x[i];
1096
1097 if (elt) {
1098 p_out[loc] = (elt == NA_LOGICAL) ? NA_INTEGER : i + 1;
1099 ++loc;
1100 }
1101 }
1102 } else {
1103 for (r_ssize i = 0; i < n; ++i) {
1104 const int elt = p_x[i];
1105
1106 if (elt) {
1107 p_out[loc] = i + 1;
1108 ++loc;
1109 }
1110 }
1111 }
1112
1113 UNPROTECT(1);
1114 return out;
1115 }
1116
1117 #define FILL() { \
1118 for (R_len_t i = 0; i < n; ++i) { \
1119 p_x[i] = value; \
1120 } \
1121 }
1122
r_p_lgl_fill(int * p_x,int value,R_len_t n)1123 void r_p_lgl_fill(int* p_x, int value, R_len_t n) {
1124 FILL();
1125 }
r_p_int_fill(int * p_x,int value,R_len_t n)1126 void r_p_int_fill(int* p_x, int value, R_len_t n) {
1127 FILL();
1128 }
r_p_chr_fill(SEXP * p_x,SEXP value,R_len_t n)1129 void r_p_chr_fill(SEXP* p_x, SEXP value, R_len_t n) {
1130 FILL();
1131 }
1132
1133 #undef FILL
1134
r_lgl_fill(SEXP x,int value,R_len_t n)1135 void r_lgl_fill(SEXP x, int value, R_len_t n) {
1136 r_p_lgl_fill(LOGICAL(x), value, n);
1137 }
r_int_fill(SEXP x,int value,R_len_t n)1138 void r_int_fill(SEXP x, int value, R_len_t n) {
1139 r_p_int_fill(INTEGER(x), value, n);
1140 }
r_chr_fill(SEXP x,SEXP value,R_len_t n)1141 void r_chr_fill(SEXP x, SEXP value, R_len_t n) {
1142 r_p_chr_fill(STRING_PTR(x), value, n);
1143 }
1144
1145
r_int_fill_seq(SEXP x,int start,R_len_t n)1146 void r_int_fill_seq(SEXP x, int start, R_len_t n) {
1147 int* data = INTEGER(x);
1148
1149 for (R_len_t i = 0; i < n; ++i, ++data, ++start) {
1150 *data = start;
1151 }
1152 }
1153
r_seq(R_len_t from,R_len_t to)1154 SEXP r_seq(R_len_t from, R_len_t to) {
1155 R_len_t n = to - from;
1156 if (n < 0) {
1157 stop_internal("r_seq", "Negative length.");
1158 }
1159
1160 SEXP seq = PROTECT(Rf_allocVector(INTSXP, n));
1161 r_int_fill_seq(seq, from, n);
1162
1163 UNPROTECT(1);
1164 return seq;
1165 }
1166
1167
1168 #define FIND(CTYPE, CONST_DEREF) \
1169 R_len_t n = Rf_length(x); \
1170 const CTYPE* data = CONST_DEREF(x); \
1171 \
1172 for (R_len_t i = 0; i < n; ++i) { \
1173 if (data[i] == value) { \
1174 return i; \
1175 } \
1176 } \
1177 return -1
1178
r_chr_find(SEXP x,SEXP value)1179 R_len_t r_chr_find(SEXP x, SEXP value) {
1180 FIND(SEXP, STRING_PTR_RO);
1181 }
1182
1183 #undef FIND
1184
1185
r_int_any_na(SEXP x)1186 bool r_int_any_na(SEXP x) {
1187 int* data = INTEGER(x);
1188 R_len_t n = Rf_length(x);
1189
1190 for (R_len_t i = 0; i < n; ++i, ++data) {
1191 if (*data == NA_INTEGER) {
1192 return true;
1193 }
1194 }
1195
1196 return false;
1197 }
1198
1199
r_chr_max_len(SEXP x)1200 int r_chr_max_len(SEXP x) {
1201 R_len_t n = Rf_length(x);
1202 SEXP const* p = STRING_PTR_RO(x);
1203
1204 int max = 0;
1205 for (R_len_t i = 0; i < n; ++i, ++p) {
1206 int len = strlen(CHAR(*p));
1207 max = len > max ? len : max;
1208 }
1209
1210 return max;
1211 }
1212
1213 /**
1214 * Create a character vector of sequential integers
1215 *
1216 * @param n The sequence is from 1 to `n`.
1217 * @param buf,len A memory buffer of size `len`.
1218 * @param prefix A null-terminated string that is prefixed to the
1219 * sequence.
1220 */
r_chr_iota(R_len_t n,char * buf,int len,const char * prefix)1221 SEXP r_chr_iota(R_len_t n, char* buf, int len, const char* prefix) {
1222 int prefix_len = strlen(prefix);
1223 if (len - 1 < prefix_len) {
1224 stop_internal("r_chr_iota", "Prefix is larger than iota buffer.");
1225 }
1226
1227 memcpy(buf, prefix, prefix_len);
1228 len -= prefix_len;
1229 char* beg = buf + prefix_len;
1230
1231 SEXP out = PROTECT(Rf_allocVector(STRSXP, n));
1232
1233 for (R_len_t i = 0; i < n; ++i) {
1234 int written = snprintf(beg, len, "%d", i + 1);
1235
1236 if (written >= len) {
1237 UNPROTECT(1);
1238 return R_NilValue;
1239 }
1240
1241 SET_STRING_ELT(out, i, Rf_mkChar(buf));
1242 }
1243
1244 UNPROTECT(1);
1245 return out;
1246 }
1247
1248
1249 #include <R_ext/Parse.h>
1250
abort_parse(SEXP code,const char * why)1251 static void abort_parse(SEXP code, const char* why) {
1252 if (Rf_GetOption1(Rf_install("rlang__verbose_errors")) != R_NilValue) {
1253 Rf_PrintValue(code);
1254 }
1255 stop_internal("r_parse", why);
1256 }
1257
r_parse(const char * str)1258 SEXP r_parse(const char* str) {
1259 SEXP str_ = PROTECT(Rf_mkString(str));
1260
1261 ParseStatus status;
1262 SEXP out = PROTECT(R_ParseVector(str_, -1, &status, R_NilValue));
1263 if (status != PARSE_OK) {
1264 abort_parse(str_, "Parsing failed.");
1265 }
1266 if (Rf_length(out) != 1) {
1267 abort_parse(str_, "Expected a single expression.");
1268 }
1269
1270 out = VECTOR_ELT(out, 0);
1271
1272 UNPROTECT(2);
1273 return out;
1274 }
r_parse_eval(const char * str,SEXP env)1275 SEXP r_parse_eval(const char* str, SEXP env) {
1276 SEXP out = Rf_eval(PROTECT(r_parse(str)), env);
1277 UNPROTECT(1);
1278 return out;
1279 }
1280
1281 static SEXP new_env_call = NULL;
1282 static SEXP new_env__parent_node = NULL;
1283 static SEXP new_env__size_node = NULL;
1284
1285 #if 0
1286 SEXP r_new_environment(SEXP parent, R_len_t size) {
1287 parent = parent ? parent : R_EmptyEnv;
1288 SETCAR(new_env__parent_node, parent);
1289
1290 size = size ? size : 29;
1291 SETCAR(new_env__size_node, Rf_ScalarInteger(size));
1292
1293 SEXP env = Rf_eval(new_env_call, R_BaseEnv);
1294
1295 // Free for gc
1296 SETCAR(new_env__parent_node, R_NilValue);
1297
1298 return env;
1299 }
1300 #endif
1301
1302 static SEXP new_function_call = NULL;
1303 static SEXP new_function__formals_node = NULL;
1304 static SEXP new_function__body_node = NULL;
1305
1306 #if 0
1307 SEXP r_new_function(SEXP formals, SEXP body, SEXP env) {
1308 SETCAR(new_function__formals_node, formals);
1309 SETCAR(new_function__body_node, body);
1310
1311 SEXP fn = Rf_eval(new_function_call, env);
1312
1313 // Free for gc
1314 SETCAR(new_function__formals_node, R_NilValue);
1315 SETCAR(new_function__body_node, R_NilValue);
1316
1317 return fn;
1318 }
1319 #endif
1320
1321 // [[ include("utils.h") ]]
r_protect(SEXP x)1322 SEXP r_protect(SEXP x) {
1323 return Rf_lang2(fns_quote, x);
1324 }
1325
1326 // [[ include("utils.h") ]]
r_is_bool(SEXP x)1327 bool r_is_bool(SEXP x) {
1328 return
1329 TYPEOF(x) == LGLSXP &&
1330 Rf_length(x) == 1 &&
1331 LOGICAL(x)[0] != NA_LOGICAL;
1332 }
r_is_true(SEXP x)1333 bool r_is_true(SEXP x) {
1334 return r_is_bool(x) && LOGICAL(x)[0] == 1;
1335 }
1336
1337 // [[ include("utils.h") ]]
r_bool_as_int(SEXP x)1338 int r_bool_as_int(SEXP x) {
1339 if (!r_is_bool(x)) {
1340 Rf_errorcall(R_NilValue, "Input must be a single `TRUE` or `FALSE`.");
1341 }
1342 return LOGICAL(x)[0];
1343 }
1344
r_is_string(SEXP x)1345 bool r_is_string(SEXP x) {
1346 return TYPEOF(x) == STRSXP &&
1347 Rf_length(x) == 1 &&
1348 STRING_ELT(x, 0) != NA_STRING;
1349 }
r_is_number(SEXP x)1350 bool r_is_number(SEXP x) {
1351 return TYPEOF(x) == INTSXP &&
1352 Rf_length(x) == 1 &&
1353 INTEGER(x)[0] != NA_INTEGER;
1354 }
r_is_positive_number(SEXP x)1355 bool r_is_positive_number(SEXP x) {
1356 return r_is_number(x) && INTEGER(x)[0] > 0;
1357 }
1358
r_peek_option(const char * option)1359 SEXP r_peek_option(const char* option) {
1360 return Rf_GetOption1(Rf_install(option));
1361 }
1362
1363 static SEXP peek_frame_call = NULL;
1364
1365 // Calling `sys.frame()` has a cost of 1.5us compared to 300ns for
1366 // `R_GetCurrentEnv()`. However the latter is currently buggy, see
1367 // https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17839.
r_peek_frame()1368 SEXP r_peek_frame() {
1369 return Rf_eval(peek_frame_call, R_EmptyEnv);
1370 }
1371
1372
1373 /**
1374 * Create a call or pairlist
1375 *
1376 * @param tags Optional. If not `NULL`, a null-terminated array of symbols.
1377 * @param cars Mandatory. A null-terminated array of CAR values.
1378 * @param fn The first CAR value of the language list.
1379 *
1380 * [[ include("utils.h") ]]
1381 */
r_pairlist(SEXP * tags,SEXP * cars)1382 SEXP r_pairlist(SEXP* tags, SEXP* cars) {
1383 if (!cars) {
1384 stop_internal("r_pairlist", "NULL `cars`.");
1385 }
1386
1387 SEXP list = PROTECT(Rf_cons(R_NilValue, R_NilValue));
1388 SEXP node = list;
1389
1390 while (*cars) {
1391 SEXP next_node = Rf_cons(*cars, R_NilValue);
1392 SETCDR(node, next_node);
1393 node = next_node;
1394
1395 if (tags) {
1396 SET_TAG(next_node, *tags);
1397 ++tags;
1398 }
1399
1400 ++cars;
1401 }
1402
1403 UNPROTECT(1);
1404 return CDR(list);
1405 }
r_call(SEXP fn,SEXP * tags,SEXP * cars)1406 SEXP r_call(SEXP fn, SEXP* tags, SEXP* cars) {
1407 return Rf_lcons(fn, r_pairlist(tags, cars));
1408 }
1409
r_has_name_at(SEXP names,R_len_t i)1410 bool r_has_name_at(SEXP names, R_len_t i) {
1411 if (TYPEOF(names) != STRSXP) {
1412 return false;
1413 }
1414
1415 R_len_t n = Rf_length(names);
1416 if (n <= i) {
1417 stop_internal("r_has_name_at", "Names shorter than expected: (%d/%d).", i + 1, n);
1418 }
1419
1420 SEXP elt = STRING_ELT(names, i);
1421 return elt != NA_STRING && elt != strings_empty;
1422 }
1423
r_is_minimal_names(SEXP x)1424 bool r_is_minimal_names(SEXP x) {
1425 if (TYPEOF(x) != STRSXP) {
1426 return false;
1427 }
1428
1429 R_len_t n = Rf_length(x);
1430 const SEXP* p = STRING_PTR_RO(x);
1431
1432 for (R_len_t i = 0; i < n; ++i, ++p) {
1433 SEXP elt = *p;
1434 if (elt == NA_STRING || elt == strings_empty) {
1435 return false;
1436 }
1437 }
1438
1439 return true;
1440 }
1441
r_is_empty_names(SEXP x)1442 bool r_is_empty_names(SEXP x) {
1443 if (TYPEOF(x) != STRSXP) {
1444 if (x == R_NilValue) {
1445 return true;
1446 } else {
1447 return false;
1448 }
1449 }
1450
1451 R_len_t n = Rf_length(x);
1452 const SEXP* p = STRING_PTR_RO(x);
1453
1454 for (R_len_t i = 0; i < n; ++i, ++p) {
1455 SEXP elt = *p;
1456 if (elt != NA_STRING && elt != strings_empty) {
1457 return false;
1458 }
1459 }
1460
1461 return true;
1462 }
1463
r_env_get(SEXP env,SEXP sym)1464 SEXP r_env_get(SEXP env, SEXP sym) {
1465 SEXP obj = PROTECT(Rf_findVarInFrame3(env, sym, FALSE));
1466
1467 // Force lazy loaded bindings
1468 if (TYPEOF(obj) == PROMSXP) {
1469 obj = Rf_eval(obj, R_BaseEnv);
1470 }
1471
1472 UNPROTECT(1);
1473 return obj;
1474 }
1475
r_is_function(SEXP x)1476 bool r_is_function(SEXP x) {
1477 switch (TYPEOF(x)) {
1478 case CLOSXP:
1479 case BUILTINSXP:
1480 case SPECIALSXP:
1481 return true;
1482 default:
1483 return false;
1484 }
1485 }
1486
r_clone_referenced(SEXP x)1487 SEXP r_clone_referenced(SEXP x) {
1488 if (MAYBE_REFERENCED(x)) {
1489 return Rf_shallow_duplicate(x);
1490 } else {
1491 return x;
1492 }
1493 }
1494
r_clone_shared(SEXP x)1495 SEXP r_clone_shared(SEXP x) {
1496 if (MAYBE_SHARED(x)) {
1497 return Rf_shallow_duplicate(x);
1498 } else {
1499 return x;
1500 }
1501 }
1502
r_is_names(SEXP names)1503 bool r_is_names(SEXP names) {
1504 if (names == R_NilValue) {
1505 return false;
1506 }
1507
1508 R_len_t n = Rf_length(names);
1509 const SEXP* p = STRING_PTR_RO(names);
1510
1511 for (R_len_t i = 0; i < n; ++i, ++p) {
1512 SEXP nm = *p;
1513 if (nm == strings_empty || nm == NA_STRING) {
1514 return false;
1515 }
1516 }
1517
1518 return true;
1519 }
1520
r_chr_has_string(SEXP x,SEXP str)1521 bool r_chr_has_string(SEXP x, SEXP str) {
1522 R_len_t n = Rf_length(x);
1523 const SEXP* xp = STRING_PTR_RO(x);
1524
1525 for (R_len_t i = 0; i < n; ++i, ++xp) {
1526 if (*xp == str) {
1527 return true;
1528 }
1529 }
1530
1531 return false;
1532 }
1533
r_as_data_frame(SEXP x)1534 SEXP r_as_data_frame(SEXP x) {
1535 if (is_bare_data_frame(x)) {
1536 return x;
1537 } else {
1538 return vctrs_dispatch1(syms_as_data_frame2, fns_as_data_frame2, syms_x, x);
1539 }
1540 }
1541
1542 SEXP rlang_formula_formals = NULL;
1543
r_as_function(SEXP x,const char * arg)1544 SEXP r_as_function(SEXP x, const char* arg) {
1545 switch (TYPEOF(x)) {
1546 case CLOSXP:
1547 case BUILTINSXP:
1548 case SPECIALSXP:
1549 return x;
1550 case LANGSXP:
1551 if (CAR(x) == syms_tilde && CDDR(x) == R_NilValue) {
1552 SEXP env = PROTECT(Rf_getAttrib(x, syms_dot_environment));
1553 if (env == R_NilValue) {
1554 Rf_errorcall(R_NilValue, "Can't transform formula to function because it doesn't have an environment.");
1555 }
1556
1557 SEXP fn = r_new_function(rlang_formula_formals, CADR(x), env);
1558
1559 UNPROTECT(1);
1560 return fn;
1561 }
1562 // else fallthrough;
1563 default:
1564 Rf_errorcall(R_NilValue, "Can't convert `%s` to a function", arg);
1565 }
1566 }
1567
1568 static SEXP syms_try_catch_hnd = NULL;
try_catch_hnd(SEXP ptr)1569 static inline SEXP try_catch_hnd(SEXP ptr) {
1570 SEXP call = PROTECT(Rf_lang2(syms_try_catch_hnd, ptr));
1571 SEXP out = Rf_eval(call, vctrs_ns_env);
1572 UNPROTECT(1);
1573 return out;
1574 }
1575
1576 struct r_try_catch_data {
1577 void (*fn)(void*);
1578 void* fn_data;
1579
1580 SEXP cnd_sym;
1581
1582 void (*hnd)(void*);
1583 void* hnd_data;
1584
1585 ERR err;
1586 };
1587
1588 // [[ register() ]]
vctrs_try_catch_callback(SEXP ptr,SEXP cnd)1589 SEXP vctrs_try_catch_callback(SEXP ptr, SEXP cnd) {
1590 struct r_try_catch_data* data = (struct r_try_catch_data*) R_ExternalPtrAddr(ptr);
1591
1592 if (cnd == R_NilValue) {
1593 if (data->fn) {
1594 data->fn(data->fn_data);
1595 }
1596 } else {
1597 data->err = cnd;
1598 if (data->hnd) {
1599 data->hnd(data->hnd_data);
1600 }
1601 }
1602
1603 return R_NilValue;
1604 }
1605
1606 static SEXP syms_try_catch_impl = NULL;
1607
1608 // [[ include("utils.h") ]]
r_try_catch(void (* fn)(void *),void * fn_data,SEXP cnd_sym,void (* hnd)(void *),void * hnd_data)1609 ERR r_try_catch(void (*fn)(void*),
1610 void* fn_data,
1611 SEXP cnd_sym,
1612 void (*hnd)(void*),
1613 void* hnd_data) {
1614
1615 struct r_try_catch_data data = {
1616 .fn = fn,
1617 .fn_data = fn_data,
1618 .cnd_sym = cnd_sym,
1619 .hnd = hnd,
1620 .hnd_data = hnd_data,
1621 .err = NULL
1622 };
1623 SEXP xptr = PROTECT(R_MakeExternalPtr(&data, R_NilValue, R_NilValue));
1624 SEXP hnd_fn = PROTECT(try_catch_hnd(xptr));
1625
1626 SEXP syms[3] = {
1627 syms_data,
1628 cnd_sym,
1629 NULL
1630 };
1631 SEXP args[3] = {
1632 xptr,
1633 hnd_fn,
1634 NULL
1635 };
1636
1637 SEXP call = PROTECT(r_call(syms_try_catch_impl, syms, args));
1638 Rf_eval(call, vctrs_ns_env);
1639
1640 UNPROTECT(3);
1641 return data.err;
1642 }
1643
1644 SEXP (*rlang_sym_as_character)(SEXP x);
1645
1646
1647 // [[ include("utils.h") ]]
chr_c(SEXP x,SEXP y)1648 SEXP chr_c(SEXP x, SEXP y) {
1649 r_ssize x_n = r_length(x);
1650 r_ssize y_n = r_length(y);
1651
1652 if (x_n == 0) {
1653 return y;
1654 }
1655 if (y_n == 0) {
1656 return x;
1657 }
1658
1659 r_ssize out_n = r_ssize_add(x_n, y_n);
1660 SEXP out = PROTECT(r_new_vector(STRSXP, out_n));
1661
1662 const SEXP* p_x = STRING_PTR_RO(x);
1663 const SEXP* p_y = STRING_PTR_RO(y);
1664
1665 for (r_ssize i = 0; i < x_n; ++i) {
1666 SET_STRING_ELT(out, i, p_x[i]);
1667 }
1668 for (r_ssize i = 0, j = x_n; i < y_n; ++i, ++j) {
1669 SET_STRING_ELT(out, j, p_y[i]);
1670 }
1671
1672 UNPROTECT(1);
1673 return out;
1674 }
1675
1676 // [[ register() ]]
vctrs_fast_c(SEXP x,SEXP y)1677 SEXP vctrs_fast_c(SEXP x, SEXP y) {
1678 SEXPTYPE x_type = TYPEOF(x);
1679
1680 if (x_type != TYPEOF(y)) {
1681 Rf_error("`x` and `y` must have the same types.");
1682 }
1683
1684 switch (x_type) {
1685 case STRSXP: return chr_c(x, y);
1686 default: stop_unimplemented_type("vctrs_fast_c", x_type);
1687 }
1688 }
1689
1690
1691 #define FMT_BUFSIZE 4096
1692 #define FMT_INTERP(BUF, FMT, DOTS) \
1693 { \
1694 va_list dots; \
1695 va_start(dots, FMT); \
1696 vsnprintf(BUF, FMT_BUFSIZE, FMT, dots); \
1697 va_end(dots); \
1698 \
1699 BUF[FMT_BUFSIZE - 1] = '\0'; \
1700 }
1701
1702 __attribute__((noreturn))
r_abort(const char * fmt,...)1703 void r_abort(const char* fmt, ...) {
1704 R_CheckStack2(FMT_BUFSIZE);
1705 char msg[FMT_BUFSIZE];
1706 FMT_INTERP(msg, fmt, ...);
1707
1708 SEXP r_msg = PROTECT(r_chr(msg));
1709 vctrs_eval_mask1(syms_abort, syms_message, r_msg);
1710
1711 never_reached("r_abort");
1712 }
1713
1714 __attribute__((noreturn))
stop_internal(const char * fn,const char * fmt,...)1715 void stop_internal(const char* fn, const char* fmt, ...) {
1716 R_CheckStack2(FMT_BUFSIZE);
1717 char msg[FMT_BUFSIZE];
1718 FMT_INTERP(msg, fmt, ...);
1719
1720 r_abort("Internal error in `%s()`: %s", fn, msg);
1721 }
1722
1723 #undef FMT_INTERP
1724 #undef FMT_BUFSIZE
1725
1726
1727 bool vctrs_debug_verbose = false;
1728
1729 SEXP vctrs_ns_env = NULL;
1730 SEXP vctrs_shared_empty_str = NULL;
1731
1732 SEXP vctrs_shared_empty_lgl = NULL;
1733 SEXP vctrs_shared_empty_int = NULL;
1734 SEXP vctrs_shared_empty_dbl = NULL;
1735 SEXP vctrs_shared_empty_cpl = NULL;
1736 SEXP vctrs_shared_empty_chr = NULL;
1737 SEXP vctrs_shared_empty_raw = NULL;
1738 SEXP vctrs_shared_empty_list = NULL;
1739 SEXP vctrs_shared_empty_date = NULL;
1740 SEXP vctrs_shared_true = NULL;
1741 SEXP vctrs_shared_false = NULL;
1742
1743 Rcomplex vctrs_shared_na_cpl;
1744 SEXP vctrs_shared_na_lgl = NULL;
1745 SEXP vctrs_shared_na_list = NULL;
1746
1747 SEXP vctrs_shared_zero_int = NULL;
1748
1749 SEXP strings = NULL;
1750 SEXP strings_empty = NULL;
1751 SEXP strings_dots = NULL;
1752 SEXP strings_none = NULL;
1753 SEXP strings_minimal = NULL;
1754 SEXP strings_unique = NULL;
1755 SEXP strings_universal = NULL;
1756 SEXP strings_check_unique = NULL;
1757 SEXP strings_key = NULL;
1758 SEXP strings_loc = NULL;
1759 SEXP strings_val = NULL;
1760 SEXP strings_group = NULL;
1761 SEXP strings_length = NULL;
1762 SEXP strings_vctrs_vctr = NULL;
1763 SEXP strings_times = NULL;
1764
1765 SEXP chrs_subset = NULL;
1766 SEXP chrs_extract = NULL;
1767 SEXP chrs_assign = NULL;
1768 SEXP chrs_rename = NULL;
1769 SEXP chrs_remove = NULL;
1770 SEXP chrs_negate = NULL;
1771 SEXP chrs_null = NULL;
1772 SEXP chrs_logical = NULL;
1773 SEXP chrs_integer = NULL;
1774 SEXP chrs_double = NULL;
1775 SEXP chrs_complex = NULL;
1776 SEXP chrs_character = NULL;
1777 SEXP chrs_raw = NULL;
1778 SEXP chrs_list = NULL;
1779 SEXP chrs_expression = NULL;
1780 SEXP chrs_numeric = NULL;
1781 SEXP chrs_function = NULL;
1782 SEXP chrs_empty = NULL;
1783 SEXP chrs_cast = NULL;
1784 SEXP chrs_error = NULL;
1785 SEXP chrs_combine = NULL;
1786 SEXP chrs_convert = NULL;
1787
1788 SEXP syms_i = NULL;
1789 SEXP syms_n = NULL;
1790 SEXP syms_x = NULL;
1791 SEXP syms_y = NULL;
1792 SEXP syms_x_size = NULL;
1793 SEXP syms_y_size = NULL;
1794 SEXP syms_to = NULL;
1795 SEXP syms_dots = NULL;
1796 SEXP syms_bracket = NULL;
1797 SEXP syms_arg = NULL;
1798 SEXP syms_x_arg = NULL;
1799 SEXP syms_y_arg = NULL;
1800 SEXP syms_to_arg = NULL;
1801 SEXP syms_times_arg = NULL;
1802 SEXP syms_subscript_arg = NULL;
1803 SEXP syms_out = NULL;
1804 SEXP syms_value = NULL;
1805 SEXP syms_quiet = NULL;
1806 SEXP syms_dot_name_spec = NULL;
1807 SEXP syms_outer = NULL;
1808 SEXP syms_inner = NULL;
1809 SEXP syms_tilde = NULL;
1810 SEXP syms_dot_environment = NULL;
1811 SEXP syms_ptype = NULL;
1812 SEXP syms_missing = NULL;
1813 SEXP syms_size = NULL;
1814 SEXP syms_subscript_action = NULL;
1815 SEXP syms_subscript_type = NULL;
1816 SEXP syms_repair = NULL;
1817 SEXP syms_tzone = NULL;
1818 SEXP syms_data = NULL;
1819 SEXP syms_vctrs_error_incompatible_type = NULL;
1820 SEXP syms_vctrs_error_cast_lossy = NULL;
1821 SEXP syms_cnd_signal = NULL;
1822 SEXP syms_logical = NULL;
1823 SEXP syms_numeric = NULL;
1824 SEXP syms_character = NULL;
1825 SEXP syms_body = NULL;
1826 SEXP syms_parent = NULL;
1827 SEXP syms_s3_methods_table = NULL;
1828 SEXP syms_from_dispatch = NULL;
1829 SEXP syms_df_fallback = NULL;
1830 SEXP syms_s3_fallback = NULL;
1831 SEXP syms_stop_incompatible_type = NULL;
1832 SEXP syms_stop_incompatible_size = NULL;
1833 SEXP syms_action = NULL;
1834 SEXP syms_vctrs_common_class_fallback = NULL;
1835 SEXP syms_fallback_class = NULL;
1836 SEXP syms_abort = NULL;
1837 SEXP syms_message = NULL;
1838 SEXP syms_chr_transform = NULL;
1839
1840 SEXP fns_bracket = NULL;
1841 SEXP fns_quote = NULL;
1842 SEXP fns_names = NULL;
1843
1844 SEXP result_attrib = NULL;
1845
1846 struct vctrs_arg args_empty_;
1847 struct vctrs_arg args_dot_ptype_;
1848 struct vctrs_arg args_max_fill_;
1849
1850
r_new_shared_vector(SEXPTYPE type,R_len_t n)1851 SEXP r_new_shared_vector(SEXPTYPE type, R_len_t n) {
1852 SEXP out = Rf_allocVector(type, n);
1853 R_PreserveObject(out);
1854 MARK_NOT_MUTABLE(out);
1855 return out;
1856 }
r_new_shared_character(const char * name)1857 SEXP r_new_shared_character(const char* name) {
1858 SEXP out = Rf_mkString(name);
1859 R_PreserveObject(out);
1860 MARK_NOT_MUTABLE(out);
1861 return out;
1862 }
1863
c_print_backtrace()1864 void c_print_backtrace() {
1865 #if defined(RLIB_DEBUG)
1866 #include <execinfo.h>
1867 void *buffer[500];
1868 int nptrs = backtrace(buffer, 100);
1869
1870 char **strings = backtrace_symbols(buffer, nptrs);
1871 for (int j = 0; j < nptrs; ++j) {
1872 Rprintf("%s\n", strings[j]);
1873 }
1874
1875 free(strings);
1876 #else
1877 Rprintf("vctrs must be compliled with -DRLIB_DEBUG.");
1878 #endif
1879 }
1880
r_browse(SEXP x)1881 void r_browse(SEXP x) {
1882 r_env_poke(R_GlobalEnv, Rf_install(".debug"), x);
1883
1884 Rprintf("Object saved in `.debug`:\n");
1885 Rf_PrintValue(x);
1886
1887 // `browser()` can't be trailing due to ESS limitations
1888 SEXP call = PROTECT(r_parse("{ base::browser(); NULL }"));
1889 Rf_eval(call, R_GlobalEnv);
1890
1891 UNPROTECT(1);
1892 }
1893
vctrs_init_utils(SEXP ns)1894 void vctrs_init_utils(SEXP ns) {
1895 vctrs_ns_env = ns;
1896
1897 vctrs_debug_verbose = r_is_true(Rf_GetOption1(Rf_install("vctrs:::debug")));
1898
1899 vctrs_method_table = r_env_get(ns, Rf_install(".__S3MethodsTable__."));
1900 base_method_table = r_env_get(R_BaseNamespace, Rf_install(".__S3MethodsTable__."));
1901
1902 s4_c_method_table = r_parse_eval("environment(methods::getGeneric('c'))$.MTable", R_GlobalEnv);
1903 R_PreserveObject(s4_c_method_table);
1904
1905 vctrs_shared_empty_str = Rf_mkString("");
1906 R_PreserveObject(vctrs_shared_empty_str);
1907
1908
1909 // Holds the CHARSXP objects because unlike symbols they can be
1910 // garbage collected
1911 strings = r_new_shared_vector(STRSXP, 21);
1912
1913 strings_dots = Rf_mkChar("...");
1914 SET_STRING_ELT(strings, 0, strings_dots);
1915
1916 strings_empty = Rf_mkChar("");
1917 SET_STRING_ELT(strings, 1, strings_empty);
1918
1919 strings_date = Rf_mkChar("Date");
1920 SET_STRING_ELT(strings, 2, strings_date);
1921
1922 strings_posixct = Rf_mkChar("POSIXct");
1923 SET_STRING_ELT(strings, 3, strings_posixct);
1924
1925 strings_posixlt = Rf_mkChar("POSIXlt");
1926 SET_STRING_ELT(strings, 4, strings_posixlt);
1927
1928 strings_posixt = Rf_mkChar("POSIXt");
1929 SET_STRING_ELT(strings, 5, strings_posixlt);
1930
1931 strings_none = Rf_mkChar("none");
1932 SET_STRING_ELT(strings, 6, strings_none);
1933
1934 strings_minimal = Rf_mkChar("minimal");
1935 SET_STRING_ELT(strings, 7, strings_minimal);
1936
1937 strings_unique = Rf_mkChar("unique");
1938 SET_STRING_ELT(strings, 8, strings_unique);
1939
1940 strings_universal = Rf_mkChar("universal");
1941 SET_STRING_ELT(strings, 9, strings_universal);
1942
1943 strings_check_unique = Rf_mkChar("check_unique");
1944 SET_STRING_ELT(strings, 10, strings_check_unique);
1945
1946 strings_key = Rf_mkChar("key");
1947 SET_STRING_ELT(strings, 11, strings_key);
1948
1949 strings_loc = Rf_mkChar("loc");
1950 SET_STRING_ELT(strings, 12, strings_loc);
1951
1952 strings_val = Rf_mkChar("val");
1953 SET_STRING_ELT(strings, 13, strings_val);
1954
1955 strings_group = Rf_mkChar("group");
1956 SET_STRING_ELT(strings, 14, strings_group);
1957
1958 strings_length = Rf_mkChar("length");
1959 SET_STRING_ELT(strings, 15, strings_length);
1960
1961 strings_factor = Rf_mkChar("factor");
1962 SET_STRING_ELT(strings, 16, strings_factor);
1963
1964 strings_ordered = Rf_mkChar("ordered");
1965 SET_STRING_ELT(strings, 17, strings_ordered);
1966
1967 strings_list = Rf_mkChar("list");
1968 SET_STRING_ELT(strings, 18, strings_list);
1969
1970 strings_vctrs_vctr = Rf_mkChar("vctrs_vctr");
1971 SET_STRING_ELT(strings, 19, strings_vctrs_vctr);
1972
1973 strings_times = Rf_mkChar("times");
1974 SET_STRING_ELT(strings, 20, strings_times);
1975
1976
1977 classes_data_frame = r_new_shared_vector(STRSXP, 1);
1978 strings_data_frame = Rf_mkChar("data.frame");
1979 SET_STRING_ELT(classes_data_frame, 0, strings_data_frame);
1980
1981 classes_factor = r_new_shared_vector(STRSXP, 1);
1982 SET_STRING_ELT(classes_factor, 0, strings_factor);
1983
1984 classes_ordered = r_new_shared_vector(STRSXP, 2);
1985 SET_STRING_ELT(classes_ordered, 0, strings_ordered);
1986 SET_STRING_ELT(classes_ordered, 1, strings_factor);
1987
1988 classes_date = r_new_shared_vector(STRSXP, 1);
1989 SET_STRING_ELT(classes_date, 0, strings_date);
1990
1991 classes_posixct = r_new_shared_vector(STRSXP, 2);
1992 SET_STRING_ELT(classes_posixct, 0, strings_posixct);
1993 SET_STRING_ELT(classes_posixct, 1, strings_posixt);
1994
1995 chrs_subset = r_new_shared_character("subset");
1996 chrs_extract = r_new_shared_character("extract");
1997 chrs_assign = r_new_shared_character("assign");
1998 chrs_rename = r_new_shared_character("rename");
1999 chrs_remove = r_new_shared_character("remove");
2000 chrs_negate = r_new_shared_character("negate");
2001 chrs_null = r_new_shared_character("NULL");
2002 chrs_logical = r_new_shared_character("logical");
2003 chrs_integer = r_new_shared_character("integer");
2004 chrs_double = r_new_shared_character("double");
2005 chrs_complex = r_new_shared_character("complex");
2006 chrs_character = r_new_shared_character("character");
2007 chrs_raw = r_new_shared_character("raw");
2008 chrs_list = r_new_shared_character("list");
2009 chrs_expression = r_new_shared_character("expression");
2010 chrs_numeric = r_new_shared_character("numeric");
2011 chrs_function = r_new_shared_character("function");
2012 chrs_empty = r_new_shared_character("");
2013 chrs_cast = r_new_shared_character("cast");
2014 chrs_error = r_new_shared_character("error");
2015 chrs_combine = r_new_shared_character("combine");
2016 chrs_convert = r_new_shared_character("convert");
2017
2018 classes_tibble = r_new_shared_vector(STRSXP, 3);
2019
2020 strings_tbl_df = Rf_mkChar("tbl_df");
2021 SET_STRING_ELT(classes_tibble, 0, strings_tbl_df);
2022
2023 strings_tbl = Rf_mkChar("tbl");
2024 SET_STRING_ELT(classes_tibble, 1, strings_tbl);
2025 SET_STRING_ELT(classes_tibble, 2, strings_data_frame);
2026
2027
2028 classes_vctrs_group_rle = r_new_shared_vector(STRSXP, 3);
2029 SET_STRING_ELT(classes_vctrs_group_rle, 0, Rf_mkChar("vctrs_group_rle"));
2030 SET_STRING_ELT(classes_vctrs_group_rle, 1, Rf_mkChar("vctrs_rcrd"));
2031 SET_STRING_ELT(classes_vctrs_group_rle, 2, Rf_mkChar("vctrs_vctr"));
2032
2033
2034 vctrs_shared_empty_lgl = r_new_shared_vector(LGLSXP, 0);
2035 vctrs_shared_empty_int = r_new_shared_vector(INTSXP, 0);
2036 vctrs_shared_empty_dbl = r_new_shared_vector(REALSXP, 0);
2037 vctrs_shared_empty_cpl = r_new_shared_vector(CPLXSXP, 0);
2038 vctrs_shared_empty_chr = r_new_shared_vector(STRSXP, 0);
2039 vctrs_shared_empty_raw = r_new_shared_vector(RAWSXP, 0);
2040 vctrs_shared_empty_list = r_new_shared_vector(VECSXP, 0);
2041 vctrs_shared_empty_date = r_new_shared_vector(REALSXP, 0);
2042 Rf_setAttrib(vctrs_shared_empty_date, R_ClassSymbol, classes_date);
2043
2044 vctrs_shared_true = r_new_shared_vector(LGLSXP, 1);
2045 LOGICAL(vctrs_shared_true)[0] = 1;
2046
2047 vctrs_shared_false = r_new_shared_vector(LGLSXP, 1);
2048 LOGICAL(vctrs_shared_false)[0] = 0;
2049
2050 vctrs_shared_na_cpl.i = NA_REAL;
2051 vctrs_shared_na_cpl.r = NA_REAL;
2052
2053 vctrs_shared_na_lgl = r_new_shared_vector(LGLSXP, 1);
2054 LOGICAL(vctrs_shared_na_lgl)[0] = NA_LOGICAL;
2055
2056 vctrs_shared_na_list = r_new_shared_vector(VECSXP, 1);
2057 SET_VECTOR_ELT(vctrs_shared_na_list, 0, R_NilValue);
2058
2059 vctrs_shared_zero_int = r_new_shared_vector(INTSXP, 1);
2060 INTEGER(vctrs_shared_zero_int)[0] = 0;
2061
2062 syms_i = Rf_install("i");
2063 syms_n = Rf_install("n");
2064 syms_x = Rf_install("x");
2065 syms_y = Rf_install("y");
2066 syms_x_size = Rf_install("x_size");
2067 syms_y_size = Rf_install("y_size");
2068 syms_to = Rf_install("to");
2069 syms_dots = Rf_install("...");
2070 syms_bracket = Rf_install("[");
2071 syms_arg = Rf_install("arg");
2072 syms_x_arg = Rf_install("x_arg");
2073 syms_y_arg = Rf_install("y_arg");
2074 syms_to_arg = Rf_install("to_arg");
2075 syms_times_arg = Rf_install("times_arg");
2076 syms_subscript_arg = Rf_install("subscript_arg");
2077 syms_out = Rf_install("out");
2078 syms_value = Rf_install("value");
2079 syms_quiet = Rf_install("quiet");
2080 syms_dot_name_spec = Rf_install(".name_spec");
2081 syms_outer = Rf_install("outer");
2082 syms_inner = Rf_install("inner");
2083 syms_tilde = Rf_install("~");
2084 syms_dot_environment = Rf_install(".Environment");
2085 syms_ptype = Rf_install("ptype");
2086 syms_missing = R_MissingArg;
2087 syms_size = Rf_install("size");
2088 syms_subscript_action = Rf_install("subscript_action");
2089 syms_subscript_type = Rf_install("subscript_type");
2090 syms_repair = Rf_install("repair");
2091 syms_tzone = Rf_install("tzone");
2092 syms_data = Rf_install("data");
2093 syms_try_catch_impl = Rf_install("try_catch_impl");
2094 syms_try_catch_hnd = Rf_install("try_catch_hnd");
2095 syms_vctrs_error_incompatible_type = Rf_install("vctrs_error_incompatible_type");
2096 syms_vctrs_error_cast_lossy = Rf_install("vctrs_error_cast_lossy");
2097 syms_cnd_signal = Rf_install("cnd_signal");
2098 syms_logical = Rf_install("logical");
2099 syms_numeric = Rf_install("numeric");
2100 syms_character = Rf_install("character");
2101 syms_body = Rf_install("body");
2102 syms_parent = Rf_install("parent");
2103 syms_s3_methods_table = Rf_install(".__S3MethodsTable__.");
2104 syms_from_dispatch = Rf_install("vctrs:::from_dispatch");
2105 syms_df_fallback = Rf_install("vctrs:::df_fallback");
2106 syms_s3_fallback = Rf_install("vctrs:::s3_fallback");
2107 syms_stop_incompatible_type = Rf_install("stop_incompatible_type");
2108 syms_stop_incompatible_size = Rf_install("stop_incompatible_size");
2109 syms_action = Rf_install("action");
2110 syms_vctrs_common_class_fallback = Rf_install(c_strs_vctrs_common_class_fallback);
2111 syms_fallback_class = Rf_install("fallback_class");
2112 syms_abort = Rf_install("abort");
2113 syms_message = Rf_install("message");
2114 syms_chr_transform = Rf_install("chr_transform");
2115
2116 fns_bracket = Rf_findVar(syms_bracket, R_BaseEnv);
2117 fns_quote = Rf_findVar(Rf_install("quote"), R_BaseEnv);
2118 fns_names = Rf_findVar(Rf_install("names"), R_BaseEnv);
2119
2120 new_env_call = r_parse_eval("as.call(list(new.env, TRUE, NULL, NULL))", R_BaseEnv);
2121 R_PreserveObject(new_env_call);
2122
2123 new_env__parent_node = CDDR(new_env_call);
2124 new_env__size_node = CDR(new_env__parent_node);
2125
2126 new_function_call = r_parse_eval("as.call(list(`function`, NULL, NULL))", R_BaseEnv);
2127 R_PreserveObject(new_function_call);
2128
2129 new_function__formals_node = CDR(new_function_call);
2130 new_function__body_node = CDR(new_function__formals_node);
2131
2132 const char* formals_code = "pairlist2(... = , .x = quote(..1), .y = quote(..2), . = quote(..1))";
2133 rlang_formula_formals = r_parse_eval(formals_code, ns);
2134 R_PreserveObject(rlang_formula_formals);
2135
2136 args_empty_ = new_wrapper_arg(NULL, "");
2137 args_dot_ptype_ = new_wrapper_arg(NULL, ".ptype");
2138 args_max_fill_ = new_wrapper_arg(NULL, "max_fill");
2139
2140 rlang_is_splice_box = (bool (*)(SEXP)) R_GetCCallable("rlang", "rlang_is_splice_box");
2141 rlang_unbox = (SEXP (*)(SEXP)) R_GetCCallable("rlang", "rlang_unbox");
2142 rlang_env_dots_values = (SEXP (*)(SEXP)) R_GetCCallable("rlang", "rlang_env_dots_values");
2143 rlang_env_dots_list = (SEXP (*)(SEXP)) R_GetCCallable("rlang", "rlang_env_dots_list");
2144 rlang_sym_as_character = (SEXP (*)(SEXP)) R_GetCCallable("rlang", "rlang_sym_as_character");
2145
2146 syms_as_data_frame2 = Rf_install("as.data.frame2");
2147 syms_colnames = Rf_install("colnames");
2148
2149 fns_as_data_frame2 = r_env_get(ns, syms_as_data_frame2);
2150 fns_colnames = r_env_get(R_BaseEnv, syms_colnames);
2151
2152 compact_seq_attrib = Rf_cons(R_NilValue, R_NilValue);
2153 R_PreserveObject(compact_seq_attrib);
2154 SET_TAG(compact_seq_attrib, Rf_install("vctrs_compact_seq"));
2155
2156 compact_rep_attrib = Rf_cons(R_NilValue, R_NilValue);
2157 R_PreserveObject(compact_rep_attrib);
2158 SET_TAG(compact_rep_attrib, Rf_install("vctrs_compact_rep"));
2159
2160 {
2161 SEXP result_names = PROTECT(Rf_allocVector(STRSXP, 2));
2162 SET_STRING_ELT(result_names, 0, Rf_mkChar("ok"));
2163 SET_STRING_ELT(result_names, 1, Rf_mkChar("err"));
2164
2165 result_attrib = PROTECT(Rf_cons(result_names, R_NilValue));
2166 SET_TAG(result_attrib, R_NamesSymbol);
2167
2168 SEXP result_class = PROTECT(Rf_allocVector(STRSXP, 1));
2169 SET_STRING_ELT(result_class, 0, Rf_mkChar("rlang_result"));
2170
2171 result_attrib = PROTECT(Rf_cons(result_class, result_attrib));
2172 SET_TAG(result_attrib, R_ClassSymbol);
2173
2174 R_PreserveObject(result_attrib);
2175 MARK_NOT_MUTABLE(result_attrib);
2176 UNPROTECT(4);
2177 }
2178
2179 // We assume the following in `union vctrs_dbl_indicator`
2180 VCTRS_ASSERT(sizeof(double) == sizeof(int64_t));
2181 VCTRS_ASSERT(sizeof(double) == 2 * sizeof(int));
2182
2183 // We assume the following in `vec_order()`
2184 VCTRS_ASSERT(sizeof(int) == sizeof(int32_t));
2185 VCTRS_ASSERT(sizeof(double) == sizeof(int64_t));
2186
2187 SEXP current_frame_body = PROTECT(r_parse_eval("as.call(list(sys.frame, -1))", R_BaseEnv));
2188 SEXP current_frame_fn = PROTECT(r_new_function(R_NilValue, current_frame_body, R_EmptyEnv));
2189 peek_frame_call = Rf_lcons(current_frame_fn, R_NilValue);
2190 R_PreserveObject(peek_frame_call);
2191 UNPROTECT(2);
2192 }
2193