Skip to content

Commit fbf75dc

Browse files
authored
Merge pull request #1871 from lionel-/feature/c-env-api
Update environment binding API with planned ctors and accessors
2 parents bae1fe1 + e8b35bf commit fbf75dc

File tree

19 files changed

+371
-171
lines changed

19 files changed

+371
-171
lines changed

.Rbuildignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@
2525
^compile_commands\.json$
2626
.*\.clangd$
2727
^[\.]?air\.toml$
28+
^dev-notes$

R/env-binding.R

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -630,25 +630,25 @@ env_binding_are_locked <- function(env, nms = NULL) {
630630
#' @return A logical vector as long as `nms` and named after it.
631631
#' @export
632632
env_binding_are_active <- function(env, nms = NULL) {
633-
env_binding_are_type(env, nms, 2L)
633+
env_binding_are_type(env, nms, 5L)
634634
}
635635
#' @rdname env_binding_are_active
636636
#' @export
637637
env_binding_are_lazy <- function(env, nms = NULL) {
638-
env_binding_are_type(env, nms, 1L)
638+
env_binding_are_type(env, nms, 3L)
639639
}
640640
env_binding_are_type <- function(env, nms, type, error_call = caller_env()) {
641641
check_environment(env, call = error_call)
642642

643643
nms <- env_binding_validate_names(env, nms, call = error_call)
644-
promise <- env_binding_types(env, nms)
644+
types <- env_binding_types(env, nms)
645645

646-
if (is_null(promise)) {
647-
promise <- rep(FALSE, length(nms))
646+
if (is_null(types)) {
647+
out <- rep(FALSE, length(nms))
648648
} else {
649-
promise <- promise == type
649+
out <- types %in% type
650650
}
651-
set_names(promise, nms)
651+
set_names(out, nms)
652652
}
653653

654654
env_binding_validate_names <- function(env, nms, call = caller_env()) {

src/internal/attr.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,8 @@ r_obj* eval_fn_dots(r_obj* fn, r_obj* x, r_obj* dots, r_obj* env) {
137137
// `.x` is the first input, x
138138
// `.fn` is the function, fn
139139
// The dots are a pairlist already in the call
140-
r_env_poke(env, r_syms.dot_x, x);
141-
r_env_poke(env, r_syms.dot_fn, fn);
140+
r_env_bind(env, r_syms.dot_x, x);
141+
r_env_bind(env, r_syms.dot_fn, fn);
142142

143143
r_obj* out = r_eval(call, env);
144144

@@ -148,13 +148,13 @@ r_obj* eval_fn_dots(r_obj* fn, r_obj* x, r_obj* dots, r_obj* env) {
148148

149149
static inline
150150
r_obj* eval_as_character(r_obj* x, r_obj* env) {
151-
r_env_poke(env, r_syms.dot_x, x);
151+
r_env_bind(env, r_syms.dot_x, x);
152152
return r_eval(as_character_call, env);
153153
}
154154

155155
static inline
156156
r_obj* names_dispatch(r_obj* x, r_obj* env) {
157-
r_env_poke(env, r_syms.dot_x, x);
157+
r_env_bind(env, r_syms.dot_x, x);
158158
return r_eval(names_call, env);
159159
}
160160

@@ -163,14 +163,14 @@ r_obj* names_dispatch(r_obj* x, r_obj* env) {
163163
// attributes using ALTREP wrappers, which is not in R's public API.
164164
static inline
165165
r_obj* set_names_dispatch(r_obj* x, r_obj* nm, r_obj* env) {
166-
r_env_poke(env, r_syms.dot_x, x);
167-
r_env_poke(env, r_syms.dot_y, nm);
166+
r_env_bind(env, r_syms.dot_x, x);
167+
r_env_bind(env, r_syms.dot_y, nm);
168168
return r_eval(set_names_call, env);
169169
}
170170

171171
static inline
172172
r_ssize length_dispatch(r_obj* x, r_obj* env) {
173-
r_env_poke(env, r_syms.dot_x, x);
173+
r_env_bind(env, r_syms.dot_x, x);
174174
r_obj* n = KEEP(r_eval(length_call, env));
175175

176176
if (r_length(n) != 1) {

src/internal/cnd-handlers.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ r_obj* ffi_try_fetch(r_obj* try_fetch_args) {
1111
// on the way out, and we could probably avoid that by switching
1212
// to or creating another variant that doesn't clone.
1313
r_obj* handlers = KEEP(rlang_env_dots_list(env));
14-
r_env_poke(env, rlang_syms.handlers, handlers);
14+
r_env_bind(env, rlang_syms.handlers, handlers);
1515

1616
if (!r_length(handlers)) {
1717
FREE(1);

src/internal/env-binding.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ r_obj* ffi_env_has(r_obj* env, r_obj* nms, r_obj* inherit) {
145145
}
146146

147147
static void env_poke_or_zap(r_obj* env, r_obj* sym, r_obj* value);
148-
static void env_poke_lazy(r_obj* env, r_obj* sym, r_obj* value, r_obj* eval_env);
148+
static void env_poke_delayed(r_obj* env, r_obj* sym, r_obj* value, r_obj* eval_env);
149149
static void env_poke_active(r_obj* env, r_obj* sym, r_obj* fn, r_obj* eval_env);
150150
static r_obj* env_get(r_obj* env, r_obj* sym);
151151

@@ -265,8 +265,8 @@ r_obj* ffi_env_bind(r_obj* env,
265265
r_env_unbind(env, sym);
266266
} else {
267267
switch (c_bind_type) {
268-
case BIND_TYPE_value: r_env_poke(env, sym, value); break;
269-
case BIND_TYPE_lazy: env_poke_lazy(env, sym, value, eval_env); break;
268+
case BIND_TYPE_value: r_env_bind(env, sym, value); break;
269+
case BIND_TYPE_lazy: env_poke_delayed(env, sym, value, eval_env); break;
270270
case BIND_TYPE_active: env_poke_active(env, sym, value, eval_env); break;
271271
}
272272
}
@@ -302,19 +302,19 @@ void env_poke_or_zap(r_obj* env, r_obj* sym, r_obj* value) {
302302
if (value == rlang_zap) {
303303
r_env_unbind(env, sym);
304304
} else {
305-
r_env_poke(env, sym, value);
305+
r_env_bind(env, sym, value);
306306
}
307307
}
308308
static
309-
void env_poke_lazy(r_obj* env, r_obj* sym, r_obj* expr, r_obj* eval_env) {
309+
void env_poke_delayed(r_obj* env, r_obj* sym, r_obj* expr, r_obj* eval_env) {
310310
if (is_quosure(expr)) {
311311
expr = KEEP(rlang_as_function(expr, eval_env));
312312
expr = r_new_call(expr, r_null);
313313
FREE(1);
314314
}
315315
KEEP(expr);
316316

317-
r_env_poke_lazy(env, sym, expr, eval_env);
317+
r_env_bind_delayed(env, sym, expr, eval_env);
318318
FREE(1);
319319
}
320320
static
@@ -324,7 +324,7 @@ void env_poke_active(r_obj* env, r_obj* sym, r_obj* fn, r_obj* eval_env) {
324324
}
325325
KEEP(fn);
326326

327-
r_env_poke_active(env, sym, fn);
327+
r_env_bind_active(env, sym, fn);
328328
FREE(1);
329329
}
330330

src/internal/eval-tidy.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,8 @@ static r_obj* restore_mask_body = NULL;
149149

150150
static void on_exit_restore_lexical_env(r_obj* mask, r_obj* old, r_obj* frame) {
151151
r_obj* env = KEEP(r_alloc_environment(2, r_envs.base));
152-
r_env_poke(env, mask_sym, mask);
153-
r_env_poke(env, old_sym, old);
152+
r_env_bind(env, mask_sym, mask);
153+
r_env_bind(env, old_sym, old);
154154

155155
r_obj* fn = KEEP(r_new_function(restore_mask_formals, restore_mask_body, env));
156156

@@ -185,10 +185,10 @@ r_obj* ffi_new_data_mask(r_obj* bottom, r_obj* top) {
185185

186186
r_obj* ctxt_pronoun = KEEP(rlang_new_ctxt_pronoun(top));
187187

188-
r_env_poke(data_mask, r_syms.tilde, tilde_fn);
189-
r_env_poke(data_mask, data_mask_flag_sym, data_mask);
190-
r_env_poke(data_mask, data_mask_env_sym, ctxt_pronoun);
191-
r_env_poke(data_mask, data_mask_top_env_sym, top);
188+
r_env_bind(data_mask, r_syms.tilde, tilde_fn);
189+
r_env_bind(data_mask, data_mask_flag_sym, data_mask);
190+
r_env_bind(data_mask, data_mask_env_sym, ctxt_pronoun);
191+
r_env_bind(data_mask, data_mask_top_env_sym, top);
192192

193193
FREE(2);
194194
return data_mask;
@@ -323,7 +323,7 @@ r_obj* ffi_as_data_mask(r_obj* data) {
323323
// Ignore empty or missing names
324324
r_obj* nm = p_names[i];
325325
if (r_str_is_name(nm)) {
326-
r_env_poke(bottom, r_str_as_symbol(nm), p_data[i]);
326+
r_env_bind(bottom, r_str_as_symbol(nm), p_data[i]);
327327
}
328328
}
329329
}
@@ -338,7 +338,7 @@ r_obj* ffi_as_data_mask(r_obj* data) {
338338
r_obj* data_mask = KEEP_N(ffi_new_data_mask(bottom, bottom), &n_kept);
339339

340340
r_obj* data_pronoun = KEEP_N(ffi_as_data_pronoun(data_mask), &n_kept);
341-
r_env_poke(bottom, data_pronoun_sym, data_pronoun);
341+
r_env_bind(bottom, data_pronoun_sym, data_pronoun);
342342

343343
FREE(n_kept);
344344
return data_mask;
@@ -492,8 +492,8 @@ r_obj* ffi_data_mask_clean(r_obj* mask) {
492492

493493
static r_obj* new_quosure_mask(r_obj* env) {
494494
r_obj* mask = KEEP(r_alloc_environment(3, env));
495-
r_env_poke(mask, r_syms.tilde, tilde_fn);
496-
r_env_poke(mask, quo_mask_flag_sym, mask);
495+
r_env_bind(mask, r_syms.tilde, tilde_fn);
496+
r_env_bind(mask, quo_mask_flag_sym, mask);
497497
FREE(1);
498498
return mask;
499499
}

src/internal/exported.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,6 +1000,15 @@ r_obj* ffi_list_poke(r_obj* x, r_obj* i, r_obj* value) {
10001000

10011001
// walk.c
10021002

1003+
r_obj* ffi_has_private_accessors(void) {
1004+
#ifdef RLANG_USE_PRIVATE_ACCESSORS
1005+
return r_true;
1006+
#else
1007+
return r_false;
1008+
#endif
1009+
}
1010+
1011+
#ifdef RLANG_USE_PRIVATE_ACCESSORS
10031012
static inline
10041013
r_obj* protect_missing(r_obj* x) {
10051014
// FIXME: Include in `exec_` functions?
@@ -1012,16 +1021,6 @@ r_obj* protect_missing(r_obj* x) {
10121021
}
10131022
}
10141023

1015-
r_obj* ffi_has_private_accessors(void) {
1016-
#ifdef RLANG_USE_PRIVATE_ACCESSORS
1017-
return r_true;
1018-
#else
1019-
return r_false;
1020-
#endif
1021-
}
1022-
1023-
#ifdef RLANG_USE_PRIVATE_ACCESSORS
1024-
10251024
// [[ register() ]]
10261025
r_obj* ffi_sexp_iterate(r_obj* x, r_obj* fn) {
10271026
struct r_dyn_array* p_out = r_new_dyn_vector(R_TYPE_list, 256);

src/rlang/cnd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ void r_abort(const char* fmt, ...) {
4343
// Evaluate in a mask but forward error call to the current frame
4444
r_obj* frame = KEEP(r_peek_frame());
4545
r_obj* mask = KEEP(r_alloc_environment(2, frame));
46-
r_env_poke(mask, r_syms.error_call_flag, frame);
46+
r_env_bind(mask, r_syms.error_call_flag, frame);
4747

4848
struct r_pair args[] = {
4949
{ r_syms.message, message }

src/rlang/debug.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ void r_sexp_inspect(r_obj* x) {
88
}
99

1010
void r_browse(r_obj* x) {
11-
r_env_poke(r_envs.global, r_sym(".debug"), x);
11+
r_env_bind(r_envs.global, r_sym(".debug"), x);
1212

1313
r_printf("Object saved in `.debug`:\n");
1414
r_obj_print(x);

src/rlang/decl/env-binding-decl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
extern r_obj* rlang_ns_env;
2+
3+
static r_obj* bind_delayed_call;
4+
static r_obj* bind_delayed_value_node;

0 commit comments

Comments
 (0)