Skip to content

Commit

Permalink
Remove private environment accessors
Browse files Browse the repository at this point in the history
  • Loading branch information
lionel- committed Jun 27, 2024
1 parent 7ead94d commit 2713fb2
Show file tree
Hide file tree
Showing 8 changed files with 29 additions and 40 deletions.
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# rlang (development version)

* The SEXP iterator of the rlang C library (used in r-lib/memtools) is now
behind a feature flag because it requires private API accessors. Compile
rlang with `-DRLANG_USE_PRIVATE_ACCESSORS` to enable it.

* `env_unlock()` is now defunct because recent versions of R no long
make it possible to unlock an environment. Make sure to use an up-to-date
version of pkgload (>= 1.4.0) following this change.
Expand Down
6 changes: 5 additions & 1 deletion R/c-lib.R
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ detect_rlang_lib_usage <- function(src_path) {
FALSE
}

has_private_accessors <- function() {
.Call(ffi_has_private_accessors)
}


# cnd.c

Expand Down Expand Up @@ -401,5 +405,5 @@ vec_resize <- function(x, n) {
# walk.c

sexp_iterate <- function(x, fn) {
.Call(ffi_sexp_iterate, x, fn)
do.call(".Call", list(ffi_sexp_iterate, x, fn))
}
6 changes: 0 additions & 6 deletions R/obj.R
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,6 @@ unmark_object <- function(x) {
true_length <- function(x) {
.Call(ffi_true_length, x)
}
env_frame <- function(x) {
.Call(ffi_env_frame, x)
}
env_hash_table <- function(x) {
.Call(ffi_env_hash_table, x)
}

promise_expr <- function(name, env = caller_env()) {
.Call(ffi_promise_expr, name, env)
Expand Down
19 changes: 12 additions & 7 deletions src/internal/exported.c
Original file line number Diff line number Diff line change
Expand Up @@ -475,13 +475,6 @@ r_obj* ffi_env_poke_parent(r_obj* env, r_obj* new_parent) {
return env;
}

r_obj* ffi_env_frame(r_obj* env) {
return FRAME(env);
}
r_obj* ffi_env_hash_table(r_obj* env) {
return HASHTAB(env);
}

r_obj* ffi_env_inherits(r_obj* env, r_obj* ancestor) {
return r_lgl(r_env_inherits(env, ancestor, r_envs.empty));
}
Expand Down Expand Up @@ -1067,6 +1060,16 @@ r_obj* protect_missing(r_obj* x) {
}
}

r_obj* ffi_has_private_accessors(void) {
#ifdef RLANG_USE_PRIVATE_ACCESSORS
return r_true;
#else
return r_false;
#endif
}

#ifdef RLANG_USE_PRIVATE_ACCESSORS

// [[ register() ]]
r_obj* ffi_sexp_iterate(r_obj* x, r_obj* fn) {
struct r_dyn_array* p_out = r_new_dyn_vector(R_TYPE_list, 256);
Expand Down Expand Up @@ -1125,3 +1128,5 @@ r_obj* ffi_sexp_iterate(r_obj* x, r_obj* fn) {
FREE(3);
return r_dyn_unwrap(p_out);
}

#endif
5 changes: 3 additions & 2 deletions src/internal/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,9 @@ static const R_CallMethodDef r_callables[] = {
{"ffi_env_browse", (DL_FUNC) &ffi_env_browse, 2},
{"ffi_env_clone", (DL_FUNC) &r_env_clone, 2},
{"ffi_env_coalesce", (DL_FUNC) &ffi_env_coalesce, 2},
{"ffi_env_frame", (DL_FUNC) &ffi_env_frame, 1},
{"ffi_env_get", (DL_FUNC) &ffi_env_get, 5},
{"ffi_env_get_list", (DL_FUNC) &ffi_env_get_list, 5},
{"ffi_env_has", (DL_FUNC) &ffi_env_has, 3},
{"ffi_env_hash_table", (DL_FUNC) &ffi_env_hash_table, 1},
{"ffi_env_inherits", (DL_FUNC) &ffi_env_inherits, 2},
{"ffi_env_is_browsed", (DL_FUNC) &ffi_env_is_browsed, 1},
{"ffi_env_poke", (DL_FUNC) &ffi_env_poke, 5},
Expand All @@ -100,6 +98,7 @@ static const R_CallMethodDef r_callables[] = {
{"ffi_glue_is_here", (DL_FUNC) &ffi_glue_is_here, 0},
{"ffi_has_dots_unnamed", (DL_FUNC) &ffi_has_dots_unnamed, 1},
{"ffi_has_local_precious_list", (DL_FUNC) &ffi_has_local_precious_list, 0},
{"ffi_has_private_accessors", (DL_FUNC) &ffi_has_private_accessors, 0},
{"ffi_has_size_one_bool", (DL_FUNC) &ffi_has_size_one_bool, 0},
{"ffi_hash", (DL_FUNC) &ffi_hash, 1},
{"ffi_hash_file", (DL_FUNC) &ffi_hash_file, 1},
Expand Down Expand Up @@ -201,7 +200,9 @@ static const R_CallMethodDef r_callables[] = {
{"ffi_replace_na", (DL_FUNC) &ffi_replace_na, 2},
{"ffi_run_c_test", (DL_FUNC) &ffi_run_c_test, 1},
{"ffi_set_names", (DL_FUNC) &ffi_set_names, 4},
#ifdef RLANG_USE_PRIVATE_ACCESSORS
{"ffi_sexp_iterate", (DL_FUNC) &ffi_sexp_iterate, 2},
#endif
{"ffi_squash", (DL_FUNC) &ffi_squash, 4},
{"ffi_standalone_check_number_1.0.7", (DL_FUNC) &ffi_standalone_check_number, 7},
{"ffi_standalone_is_bool_1.0.7", (DL_FUNC) &ffi_standalone_is_bool, 3},
Expand Down
4 changes: 3 additions & 1 deletion src/rlang/rlang.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@
#include "vec-chr.c"
#include "vec-lgl.c"
#include "vendor.c"
#include "walk.c"

#ifdef RLANG_USE_PRIVATE_ACCESSORS
#include "walk.c"
#endif

// Allows long vectors to be indexed with doubles
r_ssize r_arg_as_ssize(r_obj* n, const char* arg) {
Expand Down
2 changes: 2 additions & 0 deletions tests/testthat/test-c-api.R
Original file line number Diff line number Diff line change
Expand Up @@ -1164,6 +1164,8 @@ test_that("can push to arrays in dynamic list-of", {
})

test_that("sexp iterator visits in full order", {
skip_if_not(has_private_accessors())

it_dirs <- function(snapshot) {
dirs <- sapply(snapshot, `[[`, "dir")
dirs <- table(dirs)
Expand Down
23 changes: 0 additions & 23 deletions tests/testthat/test-env.R
Original file line number Diff line number Diff line change
Expand Up @@ -390,29 +390,6 @@ test_that("env_length() gives env length", {
expect_identical(env_length(env(a = "a")), 1L)
})

test_that("env_clone() duplicates frame", {
skip_silently("Would fail on non-GNU R")

e <- new.env(hash = FALSE)
e$x <- 1
c <- env_clone(e)
expect_false(is_reference(env_frame(e), env_frame(c)))
})

test_that("env_clone() duplicates hash table", {
skip_silently("Would fail on non-GNU R")

e <- env(x = 1)
c <- env_clone(e)

e_hash <- env_hash_table(e)
c_hash <- env_hash_table(c)
expect_false(is_reference(e_hash, c_hash))

i <- detect_index(e_hash, is_null, .p = is_false)
expect_false(is_reference(e_hash[[i]], c_hash[[i]]))
})

test_that("env_clone() increases refcounts (#621)", {
e <- env(x = 1:2)
env_bind_lazy(e, foo = 1)
Expand Down

0 comments on commit 2713fb2

Please sign in to comment.