From e505fb627a4f1b126361b2c84e3fd73572f84324 Mon Sep 17 00:00:00 2001 From: stepan <stepan.sindelar@oracle.com> Date: Tue, 18 Jul 2017 13:27:52 +0200 Subject: [PATCH] Fix match.fun used with same args from two different contexts --- .../truffle/r/nodes/builtin/base/MatchFun.java | 11 +++++++++-- .../oracle/truffle/r/test/ExpectedTestOutput.test | 13 +++++++++++++ .../r/test/builtins/TestBuiltin_matchfun.java | 5 ++++- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatchFun.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatchFun.java index 00ba7a002e..4c7fbdd5c9 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatchFun.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatchFun.java @@ -32,6 +32,7 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.dsl.TypeSystemReference; +import com.oracle.truffle.api.frame.FrameDescriptor; import com.oracle.truffle.api.frame.FrameSlot; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; @@ -124,9 +125,10 @@ public abstract class MatchFun extends RBuiltinNode.Arg2 { } @SuppressWarnings("unused") - @Specialization(limit = "LIMIT", guards = {"funValue.getLength() == 1", "funValue.getDataAt(0) == cachedName"}) + @Specialization(limit = "LIMIT", guards = {"funValue.getLength() == 1", "funValue.getDataAt(0) == cachedName", "getCallerFrameDescriptor(frame) == cachedCallerFrameDescriptor"}) protected RFunction matchfunCached(VirtualFrame frame, RPromise funPromise, RAbstractStringVector funValue, boolean descend, @Cached("firstString(funValue)") String cachedName, + @Cached("getCallerFrameDescriptor(frame)") FrameDescriptor cachedCallerFrameDescriptor, @Cached("createLookup(cachedName, descend)") ReadVariableNode lookup) { return checkResult(lookup.execute(frame, getCallerFrame.execute(frame))); } @@ -137,9 +139,10 @@ public abstract class MatchFun extends RBuiltinNode.Arg2 { } @SuppressWarnings("unused") - @Specialization(limit = "LIMIT", guards = {"funValue.getName() == cachedName"}) + @Specialization(limit = "LIMIT", guards = {"funValue.getName() == cachedName", "getCallerFrameDescriptor(frame) == cachedCallerFrameDescriptor"}) protected RFunction matchfunCached(VirtualFrame frame, RPromise funPromise, RSymbol funValue, boolean descend, @Cached("firstString(funValue)") String cachedName, + @Cached("getCallerFrameDescriptor(frame)") FrameDescriptor cachedCallerFrameDescriptor, @Cached("createLookup(cachedName, descend)") ReadVariableNode lookup) { return checkResult(lookup.execute(frame, getCallerFrame.execute(frame))); } @@ -198,5 +201,9 @@ public abstract class MatchFun extends RBuiltinNode.Arg2 { return FrameSlotChangeMonitor.getValue(slot, frame); } } + + protected FrameDescriptor getCallerFrameDescriptor(VirtualFrame frame) { + return getCallerFrame.execute(frame).getFrameDescriptor(); + } } } 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 98106c2766..995ee48459 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 @@ -35008,6 +35008,19 @@ function (..., na.rm = FALSE) .Primitive("min") #x <- min; min <- 1; f <- function() { match.fun(x, descend=T)}; f() function (..., na.rm = FALSE) .Primitive("min") +##com.oracle.truffle.r.test.builtins.TestBuiltin_matchfun.testmatchfun# +#{ foo <- function() { myfunc <- function(x) 42; lapply(2, 'myfunc'); }; boo <- function() { myfunc <- function(x) 42; lapply(2, 'myfunc'); }; list(foo = foo(), boo = boo()); } +$foo +$foo[[1]] +[1] 42 + + +$boo +$boo[[1]] +[1] 42 + + + ##com.oracle.truffle.r.test.builtins.TestBuiltin_matmul.testMatmulCorrectDimnames# #m1 <- matrix(1:6,3,2,dimnames=list(c('a','b','c'),c('c1','c2')));m2 <- matrix(c(3,4),2,1,dimnames=list(c('a2','b2'),c('col'))); m1 %*% m2; col diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_matchfun.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_matchfun.java index c18152dc17..fbf64da9f0 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_matchfun.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_matchfun.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,5 +82,8 @@ public class TestBuiltin_matchfun extends TestBase { assertEval("x <- min; f <- function(x) { min <- function(x) x; match.fun(x, descend=T)}; f(min)"); assertEval("min <- function(x) x; f <- function(x) { match.fun(x, descend=T)}; f(min)"); assertEval("f <- function(x) { match.fun(x, descend=T)}; f2 <- function() { min <- max; f(min) }; f2()"); + assertEval("{ foo <- function() { myfunc <- function(x) 42; lapply(2, 'myfunc'); }; " + + "boo <- function() { myfunc <- function(x) 42; lapply(2, 'myfunc'); }; " + + "list(foo = foo(), boo = boo()); }"); } } -- GitLab