From 8ba98add4490919b4a5350d0fa99657e9dde4842 Mon Sep 17 00:00:00 2001 From: stepan <stepan.sindelar@oracle.com> Date: Fri, 21 Jul 2017 10:49:13 +0200 Subject: [PATCH] Add test to testrffi that uses PREENV, R_PromiseExpr --- .../packages/testrffi/testrffi/R/testrffi.R | 4 ++++ .../packages/testrffi/testrffi/src/init.c | 1 + .../packages/testrffi/testrffi/src/testrffi.c | 22 +++++++++++++++++++ .../packages/testrffi/testrffi/src/testrffi.h | 2 ++ .../testrffi/testrffi/tests/simpleTests.R | 9 ++++++++ 5 files changed, 38 insertions(+) diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R index 5d51f5d371..b10b83725e 100644 --- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R +++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R @@ -164,3 +164,7 @@ rffi.ATTRIB <- function(x) { rffi.getStringNA <- function() { .Call("test_stringNA") } + +rffi.captureDotsWithSingleElement <- function(env) { + .Call('test_captureDotsWithSingleElement', env) +} diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/init.c b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/init.c index cc10d16e70..ca91702c5e 100644 --- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/init.c +++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/init.c @@ -74,6 +74,7 @@ static const R_CallMethodDef CallEntries[] = { CALLDEF(test_coerceVector, 2), CALLDEF(test_ATTRIB, 1), CALLDEF(test_stringNA, 0), + CALLDEF(test_captureDotsWithSingleElement, 1), {NULL, NULL, 0} }; diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c index 373d444e6d..28ab2aed24 100644 --- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c +++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c @@ -332,3 +332,25 @@ SEXP test_stringNA(void) { SET_STRING_ELT(x, 0, NA_STRING); return x; } + +// This function is expected to be called only with environment that has single +// promise value in the '...' variable and this is asserted inside this function. +// The return value is list with the promises' expression and environment. +SEXP test_captureDotsWithSingleElement(SEXP env) { + SEXP dots = findVarInFrame3(env, R_DotsSymbol, TRUE); + int n_dots = length(dots); + if (n_dots != 1) { + printf("Error: test_captureDotsWithSingleElement expectes single promise in ...\n"); + return R_NilValue; + } + SEXP promise = CAR(dots); + if (TYPEOF(promise) != PROMSXP) { + printf("Error: test_captureDotsWithSingleElement expectes a promise in ...\n"); + return R_NilValue; + } + SEXP info = PROTECT(allocVector(VECSXP, 2)); + SET_VECTOR_ELT(info, 0, R_PromiseExpr(promise)); + SET_VECTOR_ELT(info, 1, PRENV(promise)); + UNPROTECT(1); + return info; +} diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.h b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.h index 5c9f89bc76..981df927da 100644 --- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.h +++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.h @@ -91,3 +91,5 @@ extern SEXP test_coerceVector(SEXP x, SEXP mode); extern SEXP test_ATTRIB(SEXP); extern SEXP test_stringNA(void); + +extern SEXP test_captureDotsWithSingleElement(SEXP env); diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/simpleTests.R b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/simpleTests.R index 87e923d598..b378a50ecf 100644 --- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/simpleTests.R +++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/simpleTests.R @@ -33,3 +33,12 @@ stopifnot(attrs[[1]] == 'hello') # loess invokes loess_raw native function passing in string value as argument and that is what we test here. loess(dist ~ speed, cars); + +# code snippet that simulates work with promises ala rlang package +tmp <- c(1,2,4) +some_unique_name <- TRUE +foo <- function(...) { tmp <- 'this is not the right tmp'; bar(); } +bar <- function() rffi.captureDotsWithSingleElement(parent.frame()) +promiseInfo <- foo(tmp) +stopifnot('some_unique_name' %in% ls(promiseInfo[[2]])) +eval(promiseInfo[[1]], promiseInfo[[2]]) -- GitLab