[education/rkward/releases/0.8.3] rkward/rbackend: Make do without SET_PRx functions
Thomas Friedrichsmeier
null at kde.org
Fri Apr 17 16:32:41 BST 2026
Git commit 63bf8a9bae8588b87f55af7eaea73f9c4410e782 by Thomas Friedrichsmeier.
Committed on 17/04/2026 at 13:37.
Pushed by tfry into branch 'releases/0.8.3'.
Make do without SET_PRx functions
M +0 -2 rkward/rbackend/rkrapi.h
M +5 -8 rkward/rbackend/rkstructuregetter.cpp
M +1 -1 rkward/rbackend/rkstructuregetter.h
https://invent.kde.org/education/rkward/-/commit/63bf8a9bae8588b87f55af7eaea73f9c4410e782
diff --git a/rkward/rbackend/rkrapi.h b/rkward/rbackend/rkrapi.h
index f8b8831c8..c3b144934 100644
--- a/rkward/rbackend/rkrapi.h
+++ b/rkward/rbackend/rkrapi.h
@@ -297,8 +297,6 @@ class RFn : public QObject {
IMPORT_R_API(STRING_ELT);
IMPORT_R_API(SET_STRING_ELT);
IMPORT_R_API(SET_VECTOR_ELT);
- IMPORT_R_API(SET_PRENV);
- IMPORT_R_API(SET_PRVALUE);
IMPORT_R_API(TYPEOF);
IMPORT_R_API(VECTOR_ELT);
IMPORT_R_API(run_Rmainloop);
diff --git a/rkward/rbackend/rkstructuregetter.cpp b/rkward/rbackend/rkstructuregetter.cpp
index 2fcd18f77..d1f079431 100644
--- a/rkward/rbackend/rkstructuregetter.cpp
+++ b/rkward/rbackend/rkstructuregetter.cpp
@@ -130,11 +130,14 @@ void RKStructureGetter::getStructureSafe(SEXP value, const QString &name, int ad
*
* @note This is is not quite perfect, however. E.g. if we have two promises a and b, where b takes a slice out of a, then
* evaluating b will force a, permanently. */
-SEXP RKStructureGetter::resolvePromise(SEXP from) {
+SEXP RKStructureGetter::resolvePromise(SEXP from, SEXP env) {
RK_TRACE(RBACKEND);
SEXP ret = from;
if (RFn::TYPEOF(from) == PROMSXP) {
+ if (keep_evalled_promises) {
+ return RFn::Rf_eval(ret, env);
+ }
ret = RFn::PRVALUE(from);
if (ret == ROb(R_UnboundValue)) {
RK_DEBUG(RBACKEND, DL_TRACE, "temporarily resolving unbound promise");
@@ -144,10 +147,6 @@ SEXP RKStructureGetter::resolvePromise(SEXP from) {
// Not setting it from here, only means, any recursion will be detected one level later.
ret = RFn::Rf_eval(RFn::PRCODE(from), RFn::PRENV(from));
// SET_PRSEEN(from, 0);
- if (keep_evalled_promises) {
- RFn::SET_PRVALUE(from, ret);
- RFn::SET_PRENV(from, ROb(R_NilValue));
- }
RFn::Rf_unprotect(1);
RK_DEBUG(RBACKEND, DL_TRACE, "resolved type is %d", RFn::TYPEOF(ret));
@@ -174,8 +173,6 @@ void RKStructureGetter::getStructureWorker(SEXP val, const QString &name, int ad
SEXP value = val;
PROTECT_INDEX value_index;
RFn::R_ProtectWithIndex(value, &value_index);
- // manually resolve any promises
- RFn::R_Reprotect(value = resolvePromise(value), value_index);
bool is_s4 = RFn::Rf_isS4(value);
SEXP baseenv = ROb(R_BaseEnv);
@@ -372,7 +369,7 @@ void RKStructureGetter::getStructureWorker(SEXP val, const QString &name, int ad
for (int i = 0; i < childcount; ++i) {
SEXP current_childname = RFn::Rf_install(RFn::R_CHAR(RFn::STRING_ELT(childnames_s, i))); // ??? Why does simply using RFn::STRING_ELT(childnames_i, i) crash?
RFn::Rf_protect(current_childname);
- SEXP child = RFn::Rf_findVar(current_childname, value);
+ SEXP child = resolvePromise(RFn::Rf_findVar(current_childname, value), value);
RFn::Rf_protect(child);
getStructureSafe(child, childnames[i], 0, children[i], nesting_depth + 1);
diff --git a/rkward/rbackend/rkstructuregetter.h b/rkward/rbackend/rkstructuregetter.h
index 4951eee17..9b92bffa8 100644
--- a/rkward/rbackend/rkstructuregetter.h
+++ b/rkward/rbackend/rkstructuregetter.h
@@ -36,7 +36,7 @@ class RKStructureGetter {
/** needed to wrap things inside an R_ToplevelExec */
static void getStructureWrapper(GetStructureWorkerArgs *data);
void getStructureSafe(SEXP value, const QString &name, int add_type_flags, RData *storage, int nesting_depth);
- SEXP resolvePromise(SEXP from);
+ SEXP resolvePromise(SEXP from, SEXP env);
SEXP prefetch_fun(const char *name, bool from_base = true);
More information about the rkward-tracker
mailing list