diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/S3DispatchFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/S3DispatchFunctions.java index cbbb234aaf098b800b6c815bb94cb655b696b8af..650ab72158da049cc6119b59bdd5d7a7f471fade 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/S3DispatchFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/S3DispatchFunctions.java @@ -27,7 +27,6 @@ import com.oracle.truffle.r.nodes.access.variables.LocalReadVariableNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.function.CallMatcherNode; import com.oracle.truffle.r.nodes.function.ClassHierarchyNode; -import com.oracle.truffle.r.nodes.function.ClassHierarchyNodeGen; import com.oracle.truffle.r.nodes.function.PromiseHelperNode; import com.oracle.truffle.r.nodes.function.PromiseHelperNode.PromiseCheckHelperNode; import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode; @@ -96,7 +95,7 @@ public abstract class S3DispatchFunctions { * ignored and a warning is generated. */ - @Child private ClassHierarchyNode classHierarchyNode = ClassHierarchyNodeGen.create(true, true); + @Child private ClassHierarchyNode classHierarchyNode = ClassHierarchyNode.createForDispatch(true); @Child private PromiseCheckHelperNode promiseCheckHelper; @Child private Helper helper = new Helper(false); @@ -294,7 +293,7 @@ public abstract class S3DispatchFunctions { } if (hierarchy == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - hierarchy = insert(ClassHierarchyNode.createWithImplicit()); + hierarchy = insert(ClassHierarchyNode.createForDispatch(false)); } return hierarchy.execute(arg); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java index d5d8e0ad914e3e3c63f99e54fdf451f147224c65..1d8fccff965444f3ffc3f9f100a442e4dfab6db3 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java @@ -136,7 +136,7 @@ public abstract class AccessSlotNode extends RBaseNode { @Cached("create()") GetClassAttributeNode getClassNode) { RStringVector classAttr = getClassNode.getClassAttr(object); if (classAttr == null) { - RStringVector implicitClassVec = ImplicitClassHierarchyNode.getImplicitClass(object); + RStringVector implicitClassVec = ImplicitClassHierarchyNode.getImplicitClass(object, false); assert implicitClassVec.getLength() > 0; throw RError.error(this, RError.Message.SLOT_BASIC_CLASS, name, implicitClassVec.getDataAt(0)); } else { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java index 6a51aee479340ec59fb5b49bf3c6818c11f65971..7e8564b4ecffa5f5b5fb7e88e6c2c72bb18df1fd 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java @@ -37,6 +37,7 @@ import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNa import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.function.PromiseHelperNode; import com.oracle.truffle.r.nodes.profile.AlwaysOnBranchProfile; import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.runtime.RError; @@ -49,6 +50,7 @@ import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RLogical; import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.RPromise; import com.oracle.truffle.r.runtime.data.RString; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RTypedValue; @@ -86,6 +88,7 @@ final class CachedExtractVectorNode extends CachedVectorNode { @Child private ExtractDimNamesNode extractDimNames; private final ConditionProfile resultHasDimensions = ConditionProfile.createBinaryProfile(); + private final ConditionProfile promiseInEnvironment = ConditionProfile.createBinaryProfile(); /** * Profile if any metadata was applied at any point in time. This is useful extract primitive @@ -254,6 +257,9 @@ final class CachedExtractVectorNode extends CachedVectorNode { String positionString = tryCastSingleString(positionsCheckNode, positions); if (positionString != null) { Object obj = env.get(positionString); + if (promiseInEnvironment.profile(obj instanceof RPromise)) { + obj = PromiseHelperNode.evaluateSlowPath(null, (RPromise) obj); + } return obj == null ? RNull.instance : obj; } throw error(RError.Message.WRONG_ARGS_SUBSET_ENV); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/InternalNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/InternalNode.java index 7fceec433df39e63feb9c9b22ecee7b34d0a9d07..7b9821cf939a82abfaf28afd57fa7eda7a5fad15 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/InternalNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/InternalNode.java @@ -43,6 +43,7 @@ import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.REmpty; import com.oracle.truffle.r.runtime.data.RFunction; +import com.oracle.truffle.r.runtime.data.RPromise; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.nodes.RBaseNode; import com.oracle.truffle.r.runtime.nodes.RNode; @@ -245,6 +246,7 @@ public abstract class InternalNode extends OperatorNode { Object[] args = new Object[arguments.length]; for (int i = 0; i < args.length; i++) { args[i] = arguments[i].execute(frame); + assert !(args[i] instanceof RPromise); } return args; } @@ -273,6 +275,7 @@ public abstract class InternalNode extends OperatorNode { value = forcePromises(frame, (RArgsValuesAndNames) value); } args[i] = value; + assert !(args[i] instanceof RPromise); } return args; } @@ -281,6 +284,7 @@ public abstract class InternalNode extends OperatorNode { Object[] array = new Object[varArgs.getLength()]; for (int i = 0; i < array.length; i++) { array[i] = promiseHelper.checkEvaluate(frame, varArgs.getArgument(i)); + assert !(array[i] instanceof RPromise); } return new RArgsValuesAndNames(array, varArgs.getSignature()); } @@ -303,10 +307,12 @@ public abstract class InternalNode extends OperatorNode { for (int i = 0; i < args.length - 1; i++) { args[i] = arguments[i].execute(frame); + assert !(args[i] instanceof RPromise); } Object[] varArgs = new Object[arguments.length - (factory.getSignature().getLength() - 1)]; for (int i = 0; i < varArgs.length; i++) { varArgs[i] = arguments[args.length - 1 + i].execute(frame); + assert !(varArgs[i] instanceof RPromise); } args[args.length - 1] = new RArgsValuesAndNames(varArgs, ArgumentsSignature.empty(varArgs.length)); return args; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java index 29c1453ada068b616d66acff9b7c3d097a92095e..3400150763e1a8d057b8f1d9b6ccda5526c2028c 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java @@ -67,7 +67,7 @@ public abstract class ClassHierarchyNode extends UnaryNode { RStringVector result = null; if (value instanceof RAttributable) { Object v = ((RAttributable) value).getAttr(RRuntime.CLASS_ATTR_KEY); - result = v instanceof RStringVector ? (RStringVector) v : ImplicitClassHierarchyNode.getImplicitClass(value); + result = v instanceof RStringVector ? (RStringVector) v : ImplicitClassHierarchyNode.getImplicitClass(value, false); } return result != null ? result : RDataFactory.createEmptyStringVector(); @@ -95,13 +95,20 @@ public abstract class ClassHierarchyNode extends UnaryNode { private final boolean withImplicitTypes; private final boolean withS4; + private final boolean forDispatch; private final ConditionProfile noAttributesProfile = ConditionProfile.createBinaryProfile(); private final ConditionProfile nullAttributeProfile = ConditionProfile.createBinaryProfile(); private final ConditionProfile isS4Profile = ConditionProfile.createBinaryProfile(); - protected ClassHierarchyNode(boolean withImplicitTypes, boolean withS4) { + protected ClassHierarchyNode(boolean withImplicitTypes, boolean withS4, boolean forDispatch) { + assert !forDispatch || withImplicitTypes : "forDispatch requires withImplicitTypes"; this.withImplicitTypes = withImplicitTypes; this.withS4 = withS4; + this.forDispatch = forDispatch; + } + + protected ClassHierarchyNode(boolean withImplicitTypes, boolean withS4) { + this(withImplicitTypes, withS4, false); } public static ClassHierarchyNode create() { @@ -112,51 +119,60 @@ public abstract class ClassHierarchyNode extends UnaryNode { return ClassHierarchyNodeGen.create(true, false); } + /* + * Creates node that return result, which is meant to be used for S3 dispatch, in such case the + * "numeric" class will be preceeded by "integer" or "double" classes. This seems to be not used + * anywhere else than for the dispatch. + */ + public static ClassHierarchyNode createForDispatch(boolean withS4) { + return ClassHierarchyNodeGen.create(true, withS4, true); + } + public abstract RStringVector execute(Object arg); @Specialization protected RStringVector getClassHr(@SuppressWarnings("unused") byte arg) { - return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Logical) : null; + return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Logical, forDispatch) : null; } @Specialization protected RStringVector getClassHr(@SuppressWarnings("unused") String arg) { - return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Character) : null; + return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Character, forDispatch) : null; } @Specialization protected RStringVector getClassHr(@SuppressWarnings("unused") int arg) { - return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Integer) : null; + return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Integer, forDispatch) : null; } @Specialization protected RStringVector getClassHr(@SuppressWarnings("unused") double arg) { - return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Double) : null; + return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Double, forDispatch) : null; } @Specialization protected RStringVector getClassHr(@SuppressWarnings("unused") RComplex arg) { - return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Complex) : null; + return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Complex, forDispatch) : null; } @Specialization protected RStringVector getClassHr(@SuppressWarnings("unused") RRaw arg) { - return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Raw) : null; + return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Raw, forDispatch) : null; } @Specialization protected RStringVector getClassHr(@SuppressWarnings("unused") RNull arg) { - return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Null) : null; + return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Null, forDispatch) : null; } @Specialization protected RStringVector getClassHr(@SuppressWarnings("unused") RInteropScalar arg) { - return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(arg.getRType()) : null; + return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(arg.getRType(), forDispatch) : null; } @Specialization protected RStringVector getClassHr(@SuppressWarnings("unused") REmpty arg) { - return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Null) : null; + return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Null, forDispatch) : null; } @Specialization @@ -194,7 +210,7 @@ public abstract class ClassHierarchyNode extends UnaryNode { if (withImplicitTypes) { if (implicit == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - implicit = insert(ImplicitClassHierarchyNodeGen.create()); + implicit = insert(ImplicitClassHierarchyNodeGen.create(forDispatch)); } return implicit.execute(arg); } else { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ImplicitClassHierarchyNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ImplicitClassHierarchyNode.java index 88e4949d7df687b0ce6a2ed613a15f299f2cf969..11da7440437b0245aadd3e2767eeffd3be4f1359 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ImplicitClassHierarchyNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ImplicitClassHierarchyNode.java @@ -43,9 +43,24 @@ public abstract class ImplicitClassHierarchyNode extends UnaryNode { private static final RStringVector implicitArrayClass = ShareObjectNode.sharePermanent(RDataFactory.createStringVector("array")); private static final RStringVector implicitMatrixClass = ShareObjectNode.sharePermanent(RDataFactory.createStringVector("matrix")); + private static final RStringVector dispatchDoubleImplicitClass = ShareObjectNode.sharePermanent(RDataFactory.createStringVector(new String[]{"double", "numeric"}, RDataFactory.COMPLETE_VECTOR)); + private static final RStringVector dispatchIntegerImplicitClass = ShareObjectNode.sharePermanent(RDataFactory.createStringVector(new String[]{"integer", "numeric"}, RDataFactory.COMPLETE_VECTOR)); @CompilationFinal(dimensions = 1) private static final RStringVector[] implicitClasses = new RStringVector[RType.values().length]; - public static RStringVector getImplicitClass(RType type) { + private final boolean forDispatch; + + protected ImplicitClassHierarchyNode(boolean forDispatch) { + this.forDispatch = forDispatch; + } + + public static RStringVector getImplicitClass(RType type, boolean forDispatch) { + if (forDispatch) { + if (type == RType.Double) { + return dispatchDoubleImplicitClass; + } else if (type == RType.Integer) { + return dispatchIntegerImplicitClass; + } + } RStringVector result = implicitClasses[type.ordinal()]; if (result == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); @@ -57,27 +72,27 @@ public abstract class ImplicitClassHierarchyNode extends UnaryNode { public abstract RStringVector execute(Object arg); @Specialization - protected static RStringVector get(@SuppressWarnings("unused") int value) { - return getImplicitClass(RType.Integer); + protected RStringVector get(@SuppressWarnings("unused") int value) { + return getImplicitClass(RType.Integer, forDispatch); } @Specialization - protected static RStringVector get(@SuppressWarnings("unused") double value) { - return getImplicitClass(RType.Double); + protected RStringVector get(@SuppressWarnings("unused") double value) { + return getImplicitClass(RType.Double, forDispatch); } @Specialization - protected static RStringVector get(@SuppressWarnings("unused") String value) { - return getImplicitClass(RType.Character); + protected RStringVector get(@SuppressWarnings("unused") String value) { + return getImplicitClass(RType.Character, forDispatch); } @Specialization - protected static RStringVector get(@SuppressWarnings("unused") byte value) { - return getImplicitClass(RType.Logical); + protected RStringVector get(@SuppressWarnings("unused") byte value) { + return getImplicitClass(RType.Logical, forDispatch); } @Specialization(limit = "5", guards = "value.getClass() == valueClass") - protected static RStringVector getCachedClass(RTypedValue value, + protected RStringVector getCachedClass(RTypedValue value, @Cached("value.getClass()") Class<? extends RTypedValue> valueClass, @Cached("createBinaryProfile()") ConditionProfile isArray, @Cached("createBinaryProfile()") ConditionProfile isMatrix, @@ -86,7 +101,7 @@ public abstract class ImplicitClassHierarchyNode extends UnaryNode { } @Specialization(replaces = "getCachedClass", limit = "5", guards = "value.getRType() == type") - protected static RStringVector getCachedType(RTypedValue value, + protected RStringVector getCachedType(RTypedValue value, @Cached("value.getRType()") RType type, @Cached("createBinaryProfile()") ConditionProfile isArray, @Cached("createBinaryProfile()") ConditionProfile isMatrix, @@ -97,28 +112,28 @@ public abstract class ImplicitClassHierarchyNode extends UnaryNode { } else if (isArray.profile(GetDimAttributeNode.isArray(dimensions))) { return implicitArrayClass; } else { - return getImplicitClass(type); + return getImplicitClass(type, forDispatch); } } @Specialization(replaces = {"getCachedClass", "getCachedType"}) - protected static RStringVector get(RTypedValue value, + protected RStringVector get(RTypedValue value, @Cached("createBinaryProfile()") ConditionProfile isArray, @Cached("createBinaryProfile()") ConditionProfile isMatrix, @Cached("create()") GetDimAttributeNode getDim) { return getCachedType(value, value.getRType(), isArray, isMatrix, getDim); } - public static RStringVector getImplicitClass(Object value) { + public static RStringVector getImplicitClass(Object value, boolean forDispatch) { CompilerAsserts.neverPartOfCompilation(); if (value instanceof Integer) { - return getImplicitClass(RType.Integer); + return getImplicitClass(RType.Integer, forDispatch); } else if (value instanceof Double) { - return getImplicitClass(RType.Double); + return getImplicitClass(RType.Double, forDispatch); } else if (value instanceof String) { - return getImplicitClass(RType.Character); + return getImplicitClass(RType.Character, forDispatch); } else if (value instanceof Byte) { - return getImplicitClass(RType.Logical); + return getImplicitClass(RType.Logical, forDispatch); } else if (value instanceof RAttributable) { RAttributable attributable = (RAttributable) value; RIntVector dim = (RIntVector) attributable.getAttr(RRuntime.DIM_ATTR_KEY); @@ -131,6 +146,6 @@ public abstract class ImplicitClassHierarchyNode extends UnaryNode { } } } - return getImplicitClass(((RTypedValue) value).getRType()); + return getImplicitClass(((RTypedValue) value).getRType(), forDispatch); } } 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 ad6a7f6d381ca1e8949a34b3864d8283eab9cbc3..78cd51bfc5abb28cd3a220a3ed4a84150c667475 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 @@ -77395,6 +77395,13 @@ $named$e +##com.oracle.truffle.r.test.functions.TestS3Dispatch.runRSourceTests# +#{ source("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/functions/S3/R/numericTypes.R") } +integer +double +logical +default + ##com.oracle.truffle.r.test.functions.TestS3Dispatch.testComplexGroupDispatch# #{x<--7+2i;class(x)<-"foo";Complex.foo<-function(z){1;};Im(x);} [1] 1 @@ -78617,6 +78624,14 @@ Error in rm("foo", envir = baseenv()) : #{ x <- 1; lockBinding("x", globalenv()); x <- 1 } Error: cannot change value of locked binding for 'x' +##com.oracle.truffle.r.test.library.base.TestEnvironments.testFrameToEnv# +#{ makefun <- function(f) function(a) f(a); .Internal(islistfactor(environment(makefun(function(b) 2*b))$f, F)); } +[1] FALSE + +##com.oracle.truffle.r.test.library.base.TestEnvironments.testFrameToEnv# +#{ makefun <- function(f,s) function(a) f(a); s <- function() cat('side effect'); .Internal(islistfactor(environment(makefun(function(b) 2*b, s()))$f, F)); } +[1] FALSE + ##com.oracle.truffle.r.test.library.base.TestEnvironments.testFrames# #{ t1 <- function() { aa <- 1; t2 <- function() { cat("current frame is", sys.nframe(), "; "); cat("parents are frame numbers", sys.parents(), "; "); print(ls(envir = sys.frame(-1))) }; t2() }; t1() } current frame is 2 ; parents are frame numbers 0 1 ; [1] "aa" "t2" @@ -130688,7 +130703,7 @@ Error in attr(to, "a") <- "a" : external object cannot be attributed #if (length(grep("FastR", R.Version()$version.string)) != 1) { cat('Error in attr(to, which = "a") : external object cannot be attributed<<<NEWLINE>>>') } else { to <- .fastr.interop.new(.fastr.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); attr(to, which = 'a') } Error in attr(to, which = "a") : external object cannot be attributed -##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testClassAsParameter# +##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testClassAsParameter#Ignored.ImplementationError# #if (length(grep("FastR", R.Version()$version.string)) != 1) { "com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass" } else { tc <- .fastr.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass'); t <- .fastr.interop.new(tc); t$classAsArg(tc) } [1] "com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass" diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/functions/S3/R/numericTypes.R b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/functions/S3/R/numericTypes.R new file mode 100644 index 0000000000000000000000000000000000000000..839f61e27ca93de48854330011a291cb241eb1b5 --- /dev/null +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/functions/S3/R/numericTypes.R @@ -0,0 +1,30 @@ +# Copyright (c) 2013, 2016, 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 +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +foo <- function(x) UseMethod('foo') +foo.integer <- function(x) 'integer' +foo.double <- function(x) 'double' +foo.logical <- function(x) 'logical' +foo.numeric <- function(x) 'numeric' +foo.default <- function(x) 'default' +cat(foo(1L), "\n") +cat(foo(3.14), "\n") +cat(foo(T), "\n") +cat(foo(quote(a)), "\n") diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestEnvironments.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestEnvironments.java index 44ac9c7cfa00022ca8a01c1cd5293600ad42b13c..31bbd86d488af757a81cc21e81cce170db3c3cf0 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestEnvironments.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestEnvironments.java @@ -4,7 +4,7 @@ * http://www.gnu.org/licenses/gpl-2.0.html * * Copyright (c) 2012-2014, Purdue University - * Copyright (c) 2013, 2016, Oracle and/or its affiliates + * Copyright (c) 2013, 2017, Oracle and/or its affiliates * * All rights reserved. */ @@ -285,4 +285,12 @@ public class TestEnvironments extends TestBase { assertEval("{ e <- new.env(); assign(\"x\", 1, e); attach(e, 2); x; detach(2); x }"); assertEval("{ detach(\"missing\"); x }"); } + + @Test + public void testFrameToEnv() { + // Note: islistfactor is internal and should fail if it gets promise directly + assertEval("{ makefun <- function(f) function(a) f(a); .Internal(islistfactor(environment(makefun(function(b) 2*b))$f, F)); }"); + // Turning frame into an environment should not evaluate all the promises: + assertEval("{ makefun <- function(f,s) function(a) f(a); s <- function() cat('side effect'); .Internal(islistfactor(environment(makefun(function(b) 2*b, s()))$f, F)); }"); + } }