Skip to content

Commit 498cfad

Browse files
authored
Refactor method-dispatch.c (RConsortium#483)
* Refactor `method-dispatch.c` * (try to) run rchk in CI * refactor `method_call_` * rewrite rchk action * remove unused `is_missing()` C function. * print rchk.log in CI * pass generic dispatch args as named arg to methods * use `APPEND_NODE` helper * use `CALLDEF` macro * remove `PRCODE` and `SET_PRVALUE` usage * add `class_missing` dispatch tests * copyedit comment * avoid unnecessary allocation * fix/enable commented test case * add tests * minor edits * swap arg order in `APPEND_NODE()` helper * convert `expect_error()` test to `expect_snapshot()` * add snapshot varient for R version < 4.3
1 parent b95b192 commit 498cfad

File tree

7 files changed

+240
-71
lines changed

7 files changed

+240
-71
lines changed

.github/workflows/rchk.yml

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: rchk
2+
3+
on:
4+
workflow_dispatch:
5+
6+
7+
jobs:
8+
rchk:
9+
runs-on: ubuntu-latest
10+
steps:
11+
12+
- uses: actions/checkout@v4
13+
14+
- uses: r-lib/actions/setup-pandoc@v2
15+
- uses: r-lib/actions/setup-r@v2
16+
- uses: r-lib/actions/setup-r-dependencies@v2
17+
18+
- run: R CMD build .
19+
20+
- run: docker pull kalibera/rchk:latest
21+
22+
- name: run rchk
23+
run: |
24+
pkgtar=$(ls S7_*.tar.gz)
25+
mkdir -p rchk/packages
26+
mv $pkgtar rchk/packages/
27+
cd rchk
28+
docker run -v `pwd`/packages:/rchk/packages kalibera/rchk:latest /rchk/packages/$pkgtar > rchk.log 2>&1
29+
cat rchk.log
30+
31+
- run: cat rchk.log
32+
working-directory: rchk
33+
34+
- name: upload rchk log
35+
uses: actions/upload-artifact@v4
36+
with:
37+
name: rchk-log
38+
path: rchk/rchk.log

R/method-dispatch.R

+1-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,5 @@ method_lookup_error_message <- function(name, types) {
2020
#' @order 2
2121
#' @export
2222
S7_dispatch <- function() {
23-
S7_dispatched_call <- .Call(method_call_, sys.call(-1), sys.function(-1), sys.frame(-1))
24-
eval(S7_dispatched_call, envir = sys.frame(-1))
23+
.External2(method_call_, sys.function(-1L), sys.frame(-1L))
2524
}

src/init.c

+28-9
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,25 @@
55

66
/* .Call calls */
77
extern SEXP method_(SEXP, SEXP, SEXP, SEXP);
8-
extern SEXP method_call_(SEXP, SEXP, SEXP);
8+
extern SEXP method_call_(SEXP, SEXP, SEXP, SEXP);
9+
extern SEXP test_call_(SEXP, SEXP, SEXP, SEXP);
910
extern SEXP S7_class_(SEXP, SEXP);
1011
extern SEXP S7_object_(void);
1112
extern SEXP prop_(SEXP, SEXP);
1213
extern SEXP prop_set_(SEXP, SEXP, SEXP, SEXP);
1314

15+
#define CALLDEF(name, n) {#name, (DL_FUNC) &name, n}
16+
1417
static const R_CallMethodDef CallEntries[] = {
15-
{"method_", (DL_FUNC) &method_, 4},
16-
{"method_call_", (DL_FUNC) &method_call_, 3},
17-
{"S7_object_", (DL_FUNC) &S7_object_, 0},
18-
{"prop_", (DL_FUNC) &prop_, 2},
19-
{"prop_set_", (DL_FUNC) &prop_set_, 4},
18+
CALLDEF(method_, 4),
19+
CALLDEF(S7_object_, 0),
20+
CALLDEF(prop_, 2),
21+
CALLDEF(prop_set_, 4),
22+
{NULL, NULL, 0}
23+
};
24+
25+
static const R_ExternalMethodDef ExternalEntries[] = {
26+
CALLDEF(method_call_, 2),
2027
{NULL, NULL, 0}
2128
};
2229

@@ -35,19 +42,25 @@ SEXP sym_getter;
3542
SEXP sym_dot_should_validate;
3643
SEXP sym_dot_getting_prop;
3744
SEXP sym_dot_setting_prop;
45+
SEXP sym_obj_dispatch;
46+
SEXP sym_dispatch_args;
47+
SEXP sym_methods;
3848

3949
SEXP fn_base_quote;
50+
SEXP fn_base_missing;
4051

4152
SEXP ns_S7;
4253

54+
SEXP R_TRUE, R_FALSE;
55+
4356

4457
void R_init_S7(DllInfo *dll)
4558
{
46-
R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
59+
R_registerRoutines(dll, NULL, CallEntries, NULL, ExternalEntries);
4760
R_useDynamicSymbols(dll, FALSE);
61+
4862
sym_ANY = Rf_install("ANY");
4963
sym_S7_class = Rf_install("S7_class");
50-
5164
sym_name = Rf_install("name");
5265
sym_parent = Rf_install("parent");
5366
sym_package = Rf_install("package");
@@ -59,8 +72,14 @@ void R_init_S7(DllInfo *dll)
5972
sym_dot_should_validate = Rf_install(".should_validate");
6073
sym_dot_getting_prop = Rf_install(".getting_prop");
6174
sym_dot_setting_prop = Rf_install(".setting_prop");
75+
sym_obj_dispatch = Rf_install("obj_dispatch");
76+
sym_dispatch_args = Rf_install("dispatch_args");
77+
sym_methods = Rf_install("methods");
6278

6379
fn_base_quote = Rf_eval(Rf_install("quote"), R_BaseEnv);
80+
fn_base_missing = Rf_eval(Rf_install("missing"), R_BaseEnv);
6481

65-
ns_S7 = Rf_findVarInFrame(R_NamespaceRegistry, Rf_install("S7"));
82+
ns_S7 = Rf_eval(Rf_install("S7"), R_NamespaceRegistry);
83+
R_PreserveObject(R_TRUE = Rf_ScalarLogical(1));
84+
R_PreserveObject(R_FALSE = Rf_ScalarLogical(0));
6685
}

0 commit comments

Comments
 (0)