From 5d355cd3f99626c0c525f06bade5d9308a3dede8 Mon Sep 17 00:00:00 2001 From: Tomas Stupka <tomas.stupka@oracle.com> Date: Mon, 23 Jul 2018 15:50:20 +0200 Subject: [PATCH] implemented "get/get0" builtins with int envir argument --- .../truffle/r/nodes/builtin/base/Eval.java | 20 +- .../r/nodes/builtin/base/FrameFunctions.java | 44 ++- .../r/nodes/builtin/base/GetFunctions.java | 16 +- .../truffle/r/test/ExpectedTestOutput.test | 281 ++++++++++++++++++ .../r/test/builtins/TestBuiltin_get.java | 15 + .../r/test/builtins/TestBuiltin_sysframe.java | 16 + 6 files changed, 372 insertions(+), 20 deletions(-) diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Eval.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Eval.java index 875b596843..48072851af 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Eval.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Eval.java @@ -88,6 +88,10 @@ public abstract class Eval extends RBuiltinNode.Arg3 { @Child private RList2EnvNode rList2EnvNode; + public static EvalEnvCast create() { + return EvalEnvCastNodeGen.create(); + } + public abstract REnvironment execute(VirtualFrame frame, Object env, Object enclos); @Specialization @@ -148,16 +152,16 @@ public abstract class Eval extends RBuiltinNode.Arg3 { } @Specialization - protected REnvironment cast(VirtualFrame frame, int envirIn, @SuppressWarnings("unused") Object enclos, - @Cached("create()") SysFrame sysFrameNode) { - int envir = envirIn; - if (envirIn != 0) { - // because we are invoking SysFrame directly and normally SysFrame skips its - // .Internal frame - envir = envirIn < 0 ? envirIn + 1 : envirIn - 1; - } + protected REnvironment cast(VirtualFrame frame, int envir, @SuppressWarnings("unused") Object enclos, + @Cached("createSysFrame()") SysFrame sysFrameNode) { return sysFrameNode.executeInt(frame, envir); } + + protected static SysFrame createSysFrame() { + // SysFrame.create(skipDotInternal=true) because we are invoking SysFrame directly and + // normally SysFrame skips its .Internal frame + return SysFrame.create(true); + } } @Child private EvalEnvCast envCast = EvalEnvCastNodeGen.create(); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java index f872ce6883..e617025e13 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java @@ -114,13 +114,23 @@ public class FrameFunctions { */ private final FrameAccess access; + private final boolean ignoreDotInternal; + public FrameHelper(FrameAccess access) { + this(access, false); + } + + public FrameHelper(FrameAccess access, boolean ignoreDotInternal) { this.access = access; + this.ignoreDotInternal = ignoreDotInternal; } protected Frame getFrame(VirtualFrame frame, int n) { - int actualFrame = decodeFrameNumber(RArguments.getCall(frame), n); - return RInternalError.guaranteeNonNull(getNumberedFrame(frame, actualFrame)); + RCaller c = RArguments.getCall(frame); + int actualFrame = decodeFrameNumber(c, n); + Frame numberedFrame = getNumberedFrame(frame, actualFrame); + Frame ret = RInternalError.guaranteeNonNull(numberedFrame); + return ret; } protected RCaller getCall(VirtualFrame frame, int n) { @@ -135,7 +145,10 @@ public class FrameFunctions { */ private int decodeFrameNumber(RCaller currentCall, int n) { RCaller call = currentCall; - call = call.getParent(); // skip the .Internal function + if (!ignoreDotInternal) { + call = call.getParent(); + } + while (call.isPromise()) { call = call.getParent(); } @@ -417,10 +430,19 @@ public class FrameFunctions { @RBuiltin(name = "sys.frame", kind = INTERNAL, parameterNames = {"which"}, behavior = COMPLEX) public abstract static class SysFrame extends RBuiltinNode.Arg1 { - @Child private FrameHelper helper = new FrameHelper(FrameAccess.MATERIALIZE); + @Child private FrameHelper helper; @Child private PromiseDeoptimizeFrameNode deoptFrameNode = new PromiseDeoptimizeFrameNode(); private final ConditionProfile zeroProfile = ConditionProfile.createBinaryProfile(); + private final boolean skipDotInternal; + + public SysFrame() { + this(false); + } + + public SysFrame(boolean skipDotInternal) { + this.skipDotInternal = skipDotInternal; + } public abstract REnvironment executeInt(VirtualFrame frame, int which); @@ -428,6 +450,10 @@ public class FrameFunctions { return SysFrameNodeGen.create(); } + public static SysFrame create(boolean skipDotInternal) { + return SysFrameNodeGen.create(skipDotInternal); + } + static { Casts casts = new Casts(SysFrame.class); casts.arg("which").asIntegerVector().findFirst(); @@ -439,7 +465,7 @@ public class FrameFunctions { if (zeroProfile.profile(which == 0)) { result = REnvironment.globalEnv(); } else { - Frame callerFrame = helper.getFrame(frame, which); + Frame callerFrame = getFrameHelper().getFrame(frame, which); result = REnvironment.frameToEnvironment(callerFrame.materialize()); } @@ -447,6 +473,14 @@ public class FrameFunctions { deoptFrameNode.deoptimizeFrame(RArguments.getArguments(result.getFrame())); return result; } + + private FrameHelper getFrameHelper() { + if (helper == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + helper = insert(new FrameHelper(FrameAccess.MATERIALIZE, skipDotInternal)); + } + return helper; + } } @RBuiltin(name = "sys.frames", kind = INTERNAL, parameterNames = {}, behavior = COMPLEX) diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetFunctions.java index e5313e931c..633928a8f7 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetFunctions.java @@ -44,6 +44,7 @@ import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; import com.oracle.truffle.r.nodes.attributes.TypeFromModeNode; import com.oracle.truffle.r.nodes.attributes.TypeFromModeNodeGen; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; +import com.oracle.truffle.r.nodes.builtin.base.Eval.EvalEnvCast; import com.oracle.truffle.r.nodes.function.PromiseHelperNode; import com.oracle.truffle.r.nodes.function.call.RExplicitCallNode; import com.oracle.truffle.r.nodes.objects.GetS4DataSlot; @@ -51,7 +52,6 @@ import com.oracle.truffle.r.nodes.unary.CastNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; -import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.builtins.RBuiltin; @@ -189,10 +189,11 @@ public class GetFunctions { return get(frame, x, (REnvironment) s4ToEnv.execute(s4Envir), mode, inherits); } - @SuppressWarnings("unused") @Specialization - protected Object get(VirtualFrame frame, String x, int envir, String mode, boolean inherits) { - throw RInternalError.unimplemented(); + protected Object get(VirtualFrame frame, String x, int envir, String mode, boolean inherits, + @Cached("create()") EvalEnvCast envCast) { + Object env = envCast.execute(frame, envir, RMissing.instance); + return get(frame, x, (REnvironment) env, mode, inherits); } } @@ -233,10 +234,11 @@ public class GetFunctions { return get0(frame, x, (REnvironment) s4ToEnv.execute(s4Envir), mode, inherits, ifnotfound); } - @SuppressWarnings("unused") @Specialization - protected Object get(VirtualFrame frame, String x, int envir, String mode, boolean inherits, Object ifnotfound) { - throw RInternalError.unimplemented(); + protected Object get0(VirtualFrame frame, String x, int envir, String mode, boolean inherits, Object ifnotfound, + @Cached("create()") EvalEnvCast envCast) { + Object env = envCast.execute(frame, envir, RMissing.instance); + return get0(frame, x, (REnvironment) env, mode, inherits, ifnotfound); } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test index 11943a19ec..480198d745 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test @@ -28595,6 +28595,62 @@ In gamma(argv[[1]]) : NaNs produced #setClass('foo', representation(x='numeric')); f <- new('foo'); e <- new.env(); e$x <- 1; attr(f, '.xData') <- e; get('x', envir=f) [1] 1 +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ f <- function() { xx <- 'xv'; f1 <- function() get('xx', envir = -1); f1()}; f() } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ f <- function() { xx <- 'xv'; f1 <- function() get('xx', envir = -2); f1()}; f() } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ f <- function() { xx <- 'xv'; f1 <- function() get('xx', envir = -3); f1()}; f() } +Error in get("xx", envir = -3) : object 'xx' not found + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ f <- function() { xx <- 'xv'; f1 <- function() get('xx', envir = 0); f1()}; f() } +Error in get("xx", envir = 0) : object 'xx' not found + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ f <- function() { xx <- 'xv'; f1 <- function() get('xx', envir = 1); f1()}; f() } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ f <- function() { xx <- 'xv'; f1 <- function() get('xx', envir = 2); f1()}; f() } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ f <- function() { xx <- 'xv'; f1 <- function() get('xx', envir = 3); f1()}; f() } +Error in get("xx", envir = 3) : object 'xx' not found + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ f <- function() { xx <- 'xv'; f1 <- function() get0('xx', envir = -1, ifnotfound = 'DNF'); f1()}; f() } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ f <- function() { xx <- 'xv'; f1 <- function() get0('xx', envir = -2, ifnotfound = 'DNF'); f1()}; f() } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ f <- function() { xx <- 'xv'; f1 <- function() get0('xx', envir = -3, ifnotfound = 'DNF'); f1()}; f() } +[1] "DNF" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ f <- function() { xx <- 'xv'; f1 <- function() get0('xx', envir = 0, ifnotfound = 'DNF'); f1()}; f() } +[1] "DNF" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ f <- function() { xx <- 'xv'; f1 <- function() get0('xx', envir = 1, ifnotfound = 'DNF'); f1()}; f() } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ f <- function() { xx <- 'xv'; f1 <- function() get0('xx', envir = 2, ifnotfound = 'DNF'); f1()}; f() } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ f <- function() { xx <- 'xv'; f1 <- function() get0('xx', envir = 3, ifnotfound = 'DNF'); f1()}; f() } +[1] "DNF" + ##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# #{ get(".Platform")$endian } [1] "little" @@ -28607,6 +28663,26 @@ In gamma(argv[[1]]) : NaNs produced #{ get("dummy") } Error in get("dummy") : object 'dummy' not found +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ x <- 'xv'; get('x', envir = -1) } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ x <- 'xv'; get('x', envir = -2) } +Error in get("x", envir = -2) : not that many frames on the stack + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ x <- 'xv'; get('x', envir = 0) } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ x <- 'xv'; get('x', envir = 1) } +[1] "x" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ x <- 'xv'; get('x', envir = 2) } +Error in get("x", envir = 2) : not that many frames on the stack + ##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# #{ x <- 33 ; f <- function() { get("x", inherits = FALSE) } ; f() } Error in get("x", inherits = FALSE) : object 'x' not found @@ -28615,6 +28691,106 @@ Error in get("x", inherits = FALSE) : object 'x' not found #{ x <- 33 ; f <- function() { if (FALSE) { x <- 22 } ; get("x", inherits = FALSE) } ; f() } Error in get("x", inherits = FALSE) : object 'x' not found +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; f <- function() { get('xx', envir = -1)}; f() } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; f <- function() { get('xx', envir = -2)}; f() } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; f <- function() { get('xx', envir = -3)}; f() } +Error in get("xx", envir = -3) : not that many frames on the stack + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; f <- function() { get('xx', envir = 0)}; f() } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; f <- function() { get('xx', envir = 1)}; f() } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; f <- function() { get('xx', envir = 2)}; f() } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; f <- function() { get('xx', envir = 3)}; f() } +Error in get("xx", envir = 3) : not that many frames on the stack + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; f <- function() { get0('xx', envir = -1, ifnotfound = 'DNF')}; f() } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; f <- function() { get0('xx', envir = -2, ifnotfound = 'DNF')}; f() } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; f <- function() { get0('xx', envir = -3, ifnotfound = 'DNF')}; f() } +Error in get0("xx", envir = -3, ifnotfound = "DNF") : + not that many frames on the stack + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; f <- function() { get0('xx', envir = 0, ifnotfound = 'DNF')}; f() } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; f <- function() { get0('xx', envir = 1, ifnotfound = 'DNF')}; f() } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; f <- function() { get0('xx', envir = 2, ifnotfound = 'DNF')}; f() } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; f <- function() { get0('xx', envir = 3, ifnotfound = 'DNF')}; f() } +Error in get0("xx", envir = 3, ifnotfound = "DNF") : + not that many frames on the stack + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; get('xx', envir =-1) } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; get('xx', envir =-2) } +Error in get("xx", envir = -2) : not that many frames on the stack + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; get('xx', envir =0) } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; get('xx', envir =1) } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; get('xx', envir =2) } +Error in get("xx", envir = 2) : not that many frames on the stack + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; get0('xx', envir = -1, ifnotfound = 'DNF') } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; get0('xx', envir = -2, ifnotfound = 'DNF') } +Error in get0("xx", envir = -2, ifnotfound = "DNF") : + not that many frames on the stack + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; get0('xx', envir = 0, ifnotfound = 'DNF') } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; get0('xx', envir = 1, ifnotfound = 'DNF') } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# +#{ xx <- 'xv'; get0('xx', envir = 2, ifnotfound = 'DNF') } +Error in get0("xx", envir = 2, ifnotfound = "DNF") : + not that many frames on the stack + ##com.oracle.truffle.r.test.builtins.TestBuiltin_get.testGet# #{x <- 1L; get('x', mode='double'); } [1] 1 @@ -75424,6 +75600,111 @@ v() [1] "x" +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval# +#{ f <- function() { xx <- 'xv'; f1 <- function() get('xx', envir = -1); xy <- new.env(); xy$xx <- 'aa'; eval(parse(text='f1()'), envir=xy)}; f() } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval# +#{ f <- function() { xx <- 'xv'; f1 <- function() get('xx', envir = -2); xy <- new.env(); xy$xx <- 'aa'; eval(parse(text='f1()'), envir=xy)}; f() } +[1] "aa" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval# +#{ f <- function() { xx <- 'xv'; f1 <- function() get('xx', envir = -3); xy <- new.env(); xy$xx <- 'aa'; eval(parse(text='f1()'), envir=xy)}; f() } +Error in get("xx", envir = -3) : object 'xx' not found + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval# +#{ f <- function() { xx <- 'xv'; f1 <- function() get('xx', envir = -4); xy <- new.env(); xy$xx <- 'aa'; eval(parse(text='f1()'), envir=xy)}; f() } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval# +#{ f <- function() { xx <- 'xv'; f1 <- function() get('xx', envir = -6); xy <- new.env(); xy$xx <- 'aa'; eval(parse(text='f1()'), envir=xy)}; f() } +Error in get("xx", envir = -6) : not that many frames on the stack + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval# +#{ f <- function() { xx <- 'xv'; f1 <- function() get('xx', envir = 0); xy <- new.env(); xy$xx <- 'aa'; eval(parse(text='f1()'), envir=xy)}; f() } +Error in get("xx", envir = 0) : object 'xx' not found + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval# +#{ f <- function() { xx <- 'xv'; f1 <- function() get('xx', envir = 1); xy <- new.env(); xy$xx <- 'aa'; eval(parse(text='f1()'), envir=xy)}; f() } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval# +#{ f <- function() { xx <- 'xv'; f1 <- function() get('xx', envir = 2); xy <- new.env(); xy$xx <- 'aa'; eval(parse(text='f1()'), envir=xy)}; f() } +Error in get("xx", envir = 2) : object 'xx' not found + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval# +#{ f <- function() { xx <- 'xv'; f1 <- function() get('xx', envir = 3); xy <- new.env(); xy$xx <- 'aa'; eval(parse(text='f1()'), envir=xy)}; f() } +[1] "aa" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval# +#{ f <- function() { xx <- 'xv'; f1 <- function() get('xx', envir = 4); xy <- new.env(); xy$xx <- 'aa'; eval(parse(text='f1()'), envir=xy)}; f() } +[1] "xv" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval# +#{ f <- function() { xx <- 'xv'; f1 <- function() get('xx', envir = 5); xy <- new.env(); xy$xx <- 'aa'; eval(parse(text='f1()'), envir=xy)}; f() } +Error in get("xx", envir = 5) : object 'xx' not found + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval# +#{ f <- function() { xx <- 'xv'; f1 <- function() get('xx', envir = 6); xy <- new.env(); xy$xx <- 'aa'; eval(parse(text='f1()'), envir=xy)}; f() } +Error in get("xx", envir = 6) : not that many frames on the stack + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval# +#{ f <- function() { xx <- 'xv'; f1 <- function() ls(sys.frame(-1)); eval(parse(text='f1()'), envir=environment())}; f() } +[1] "f1" "xx" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval#Ignored.ImplementationError# +#{ f <- function() { xx <- 'xv'; f1 <- function() ls(sys.frame(-2)); eval(parse(text='f1()'), envir=environment())}; f() } +[1] "enclos" "envir" "expr" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval#Ignored.ImplementationError# +#{ f <- function() { xx <- 'xv'; f1 <- function() ls(sys.frame(-3)); eval(parse(text='f1()'), envir=environment())}; f() } +[1] "f1" "xx" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval#Ignored.ImplementationError# +#{ f <- function() { xx <- 'xv'; f1 <- function() ls(sys.frame(-4)); eval(parse(text='f1()'), envir=environment())}; f() } +[1] "f" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval#Ignored.ImplementationError# +#{ f <- function() { xx <- 'xv'; f1 <- function() ls(sys.frame(-6)); eval(parse(text='f1()'), envir=environment())}; f() } +Error in as.environment(pos) : + no item called "sys.frame(-6)" on the search list +In addition: Warning message: +In ls(sys.frame(-6)) : ‘sys.frame(-6)’ converted to character string + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval# +#{ f <- function() { xx <- 'xv'; f1 <- function() ls(sys.frame(0)); eval(parse(text='f1()'), envir=environment())}; f() } +[1] "f" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval# +#{ f <- function() { xx <- 'xv'; f1 <- function() ls(sys.frame(1)); eval(parse(text='f1()'), envir=environment())}; f() } +[1] "f1" "xx" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval#Ignored.ImplementationError# +#{ f <- function() { xx <- 'xv'; f1 <- function() ls(sys.frame(2)); eval(parse(text='f1()'), envir=environment())}; f() } +[1] "enclos" "envir" "expr" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval#Ignored.ImplementationError# +#{ f <- function() { xx <- 'xv'; f1 <- function() ls(sys.frame(3)); eval(parse(text='f1()'), envir=environment())}; f() } +[1] "f1" "xx" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval#Ignored.ImplementationError# +#{ f <- function() { xx <- 'xv'; f1 <- function() ls(sys.frame(4)); eval(parse(text='f1()'), envir=environment())}; f() } +character(0) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval#Ignored.ImplementationError# +#{ f <- function() { xx <- 'xv'; f1 <- function() ls(sys.frame(5)); eval(parse(text='f1()'), envir=environment())}; f() } +Error in as.environment(pos) : + no item called "sys.frame(5)" on the search list +In addition: Warning message: +In ls(sys.frame(5)) : ‘sys.frame(5)’ converted to character string + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameViaEval#Ignored.ImplementationError# +#{ f <- function() { xx <- 'xv'; f1 <- function() ls(sys.frame(6)); eval(parse(text='f1()'), envir=environment())}; f() } +Error in as.environment(pos) : + no item called "sys.frame(6)" on the search list +In addition: Warning message: +In ls(sys.frame(6)) : ‘sys.frame(6)’ converted to character string + ##com.oracle.truffle.r.test.builtins.TestBuiltin_sysframe.sysFrameWithPromises# #{ top <- function(vtop) vtop;foo <- function(vfoo) top(vfoo);boo <- function(vboo) foo(sys.frame(vboo));bar <- function(vbar) do.call(boo, list(vbar), envir = parent.frame(2));baz <- function(vbaz) bar(vbaz);start <- function(vstart) baz(vstart);lapply(lapply(0:8, function(i) start(i)), function(env) sort(tolower(ls(env)))); } [[1]] diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_get.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_get.java index 78e5b30b84..ccbb403f7b 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_get.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_get.java @@ -27,6 +27,9 @@ import com.oracle.truffle.r.test.TestBase; // Checkstyle: stop line length check public class TestBuiltin_get extends TestBase { + private final String[] envirValues2 = {"-2", "-1", "0", "1", "2"}; + private final String[] envirValues3 = {"-3", "-2", "-1", "0", "1", "2", "3"}; + @Test public void testGet() { assertEval("{y<-function(){y<-2;get(\"y\",mode=\"integer\")};y();}"); @@ -47,5 +50,17 @@ public class TestBuiltin_get extends TestBase { assertEval("{x <- 1L; get('x', mode='numeric'); }"); assertEval("{x <- 1L; get('x', mode='double'); }"); + + // get('x', envir = 0) => [1] "xv" + // get('x', envir = 1) => [1] "x" + assertEval(template("{ x <- 'xv'; get('x', envir = %0) }", envirValues2)); + + assertEval(template("{ xx <- 'xv'; get('xx', envir =%0) }", envirValues2)); + assertEval(template("{ xx <- 'xv'; f <- function() { get('xx', envir = %0)}; f() }", envirValues3)); + assertEval(template("{ f <- function() { xx <- 'xv'; f1 <- function() get('xx', envir = %0); f1()}; f() }", envirValues3)); + + assertEval(template("{ xx <- 'xv'; get0('xx', envir = %0, ifnotfound = 'DNF') }", envirValues2)); + assertEval(template("{ xx <- 'xv'; f <- function() { get0('xx', envir = %0, ifnotfound = 'DNF')}; f() }", envirValues3)); + assertEval(template("{ f <- function() { xx <- 'xv'; f1 <- function() get0('xx', envir = %0, ifnotfound = 'DNF'); f1()}; f() }", envirValues3)); } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_sysframe.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_sysframe.java index 73cee66097..7ba7a4d9ae 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_sysframe.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_sysframe.java @@ -46,4 +46,20 @@ public class TestBuiltin_sysframe extends TestBase { "start <- function(vstart) baz(vstart);" + "lapply(lapply(0:8, function(i) start(i)), function(env) sort(tolower(ls(env)))); }"); } + + private final String[] envirValues = {"-6", "-4", "-3", "-2", "-1", "0", "1", "2", "3", "4", "5", "6"}; + + @Test + public void sysFrameViaEval() { + assertEval(template("{ f <- function() { xx <- 'xv'; f1 <- function() get('xx', envir = %0); xy <- new.env(); xy$xx <- 'aa'; eval(parse(text='f1()'), envir=xy)}; f() }", envirValues)); + + for (String envirValue : envirValues) { + String input = "{ f <- function() { xx <- 'xv'; f1 <- function() ls(sys.frame(" + envirValue + ")); eval(parse(text='f1()'), envir=environment())}; f() }"; + if (Math.abs(Integer.parseInt(envirValue)) > 1) { + assertEval(Ignored.ImplementationError, input); + } else { + assertEval(input); + } + } + } } -- GitLab