@@ -58,6 +58,22 @@ static_inline void holes_clear(SEXP self) {
5858 UNPROTECT (3 );
5959}
6060
61+ #if R_VERSION < R_Version (4 , 5 , 0 )
62+ # define R_ClosureFormals (x ) FORMALS(x)
63+ # define R_ClosureBody (x ) BODY(x)
64+
65+ SEXP R_mkClosure (SEXP formals , SEXP body , SEXP env )
66+ {
67+ SEXP fun = Rf_allocSExp (CLOSXP );
68+ SET_FORMALS (fun , formals );
69+ SET_BODY (fun , body );
70+ SET_CLOENV (fun , env );
71+ return fun ;
72+ }
73+
74+ #endif
75+
76+
6177tommy_hash_t key_to_u64 (SEXP key ) {
6278 if (is_hashable (key )) {
6379 return xxh_digest (key );
@@ -70,10 +86,8 @@ tommy_hash_t key_to_u64(SEXP key) {
7086 }
7187
7288 if (Rf_isFunction (key )) {
73- SEXP key2 = PROTECT (Rf_shallow_duplicate (key ));
7489 // avoid R_Serialize serilizing the closure environment and attributes
75- SET_CLOENV (key2 , R_NilValue );
76- SET_ATTRIB (key2 , R_NilValue );
90+ SEXP key2 = PROTECT (R_mkClosure (R_ClosureFormals (key ), R_ClosureBody (key ), R_GlobalEnv ));
7791 tommy_hash_t h = xxh_serialized_digest (key2 );
7892 UNPROTECT (1 );
7993 return h ;
@@ -159,7 +173,7 @@ SEXP dict_get(SEXP self, SEXP _key) {
159173 Rf_error ("key not found" );
160174 } else {
161175 SEXP _default = PROTECT (Rf_findVar (Rf_install ("default" ), fn ));
162- _default = Rf_eval (_default , PRENV ( _default ) );
176+ _default = Rf_eval (_default , fn );
163177 UNPROTECT (2 );
164178 return _default ;
165179 }
0 commit comments