Skip to content

Commit 8e83c03

Browse files
author
Pavel Marek
committed
[GR-32296] Backport of "Add tests for vctrs and tibble".
PullRequest: fastr/2634
2 parents e0d2ce8 + 97f29e0 commit 8e83c03

File tree

28 files changed

+1047
-161
lines changed

28 files changed

+1047
-161
lines changed

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
# 21.2.0
2+
* Support for packages in 2021-02-01 CRAN snapshot:
3+
* testthat 3.0.1 is partially supported.
4+
* FastR does not support parallel tests run, i.e. run testthat only with `Sys.setenv(TESTTHAT_PARALLEL="false")`.
5+
* tibble 3.0.6 , vctrs 0.3.6, and data.table 1.13.6 are mostly supported.
6+
* Support for dplyr 1.0.3, ggplot 3.3.3, and knitr 1.31 is a work in progress.
7+
8+
Bug fixes:
9+
10+
* `read.dcf` does not ignore whitespaces in fields any more.
11+
* `list.files` gives correct result in a subdirectory with the same prefix as its parent directory.
12+
* Whitespaces in quantifiers in regular expressions are ignored.
13+
* GNU-R does not comply with PCRE with this behavior.
14+
* `sys.frame` displays frames for `NextMethod` correctly.
15+
* `parent.frame` is able to get the frame that is no longer on the stack.
16+
* Which is not recommended due to the documentation of `parent.frame`, but some packages do that nonetheless.
17+
118
# 21.1.0
219

320
* Upgraded FastR to R 4.0.3

com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -437,19 +437,8 @@ public Object Rf_allocVector(int mode, long n) {
437437
}
438438

439439
@Override
440-
@TruffleBoundary
441440
public Object Rf_allocArray(int mode, Object dimsObj) {
442-
RIntVector dims = (RIntVector) dimsObj;
443-
int n = 1;
444-
int[] newDims = new int[dims.getLength()];
445-
// TODO check long vector
446-
for (int i = 0; i < newDims.length; i++) {
447-
newDims[i] = dims.getDataAt(i);
448-
n *= newDims[i];
449-
}
450-
RAbstractVector result = (RAbstractVector) Rf_allocVector(mode, n);
451-
setDims(newDims, result);
452-
return result;
441+
throw implementedAsNode();
453442
}
454443

455444
@Override

com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/AsCharNode.java

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -26,17 +26,20 @@
2626
import com.oracle.truffle.api.dsl.Fallback;
2727
import com.oracle.truffle.api.dsl.Specialization;
2828
import com.oracle.truffle.api.dsl.TypeSystemReference;
29+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
30+
import com.oracle.truffle.api.library.CachedLibrary;
2931
import com.oracle.truffle.api.profiles.ConditionProfile;
3032
import com.oracle.truffle.r.nodes.unary.CastStringNode;
3133
import com.oracle.truffle.r.runtime.RInternalError;
3234
import com.oracle.truffle.r.runtime.RRuntime;
3335
import com.oracle.truffle.r.runtime.data.CharSXPWrapper;
36+
import com.oracle.truffle.r.runtime.data.RComplexVector;
3437
import com.oracle.truffle.r.runtime.data.RDoubleVector;
38+
import com.oracle.truffle.r.runtime.data.RStringVector;
3539
import com.oracle.truffle.r.runtime.data.RSymbol;
3640
import com.oracle.truffle.r.runtime.data.RTypes;
41+
import com.oracle.truffle.r.runtime.data.VectorDataLibrary;
3742
import com.oracle.truffle.r.runtime.data.model.RAbstractAtomicVector;
38-
import com.oracle.truffle.r.runtime.data.RComplexVector;
39-
import com.oracle.truffle.r.runtime.data.RStringVector;
4043

4144
@TypeSystemReference(RTypes.class)
4245
public abstract class AsCharNode extends FFIUpCallNode.Arg1 {
@@ -51,14 +54,21 @@ protected CharSXPWrapper asChar(CharSXPWrapper obj) {
5154
}
5255

5356
@Specialization
54-
protected CharSXPWrapper asChar(RStringVector obj, @Cached("createBinaryProfile()") ConditionProfile profile, @Cached("createBinaryProfile()") ConditionProfile naProfile,
55-
@Cached("createBinaryProfile()") ConditionProfile isNativized,
56-
@Cached("createBinaryProfile()") ConditionProfile wrapProfile) {
57-
if (profile.profile(obj.getLength() == 0)) {
57+
protected CharSXPWrapper asChar(RStringVector obj,
58+
@Cached("createBinaryProfile()") ConditionProfile zeroLengthProfile,
59+
@Cached("createBinaryProfile()") ConditionProfile naProfile,
60+
@CachedLibrary(limit = "getTypedVectorDataLibraryCacheSize()") VectorDataLibrary dataLib) {
61+
if (zeroLengthProfile.profile(obj.getLength() == 0)) {
5862
return CharSXPWrapper_NA;
5963
} else {
60-
obj.wrapStrings(isNativized, wrapProfile);
61-
CharSXPWrapper result = obj.getWrappedDataAt(0);
64+
Object newCharSXPData = null;
65+
try {
66+
newCharSXPData = dataLib.materializeCharSXPStorage(obj.getData());
67+
} catch (UnsupportedMessageException e) {
68+
throw RInternalError.shouldNotReachHere(e);
69+
}
70+
obj.setData(newCharSXPData);
71+
CharSXPWrapper result = dataLib.getCharSXPAt(obj.getData(), 0);
6272
return naProfile.profile(RRuntime.isNA(result.getContents())) ? CharSXPWrapper_NA : result;
6373
}
6474
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 3 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 3 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 3 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
package com.oracle.truffle.r.ffi.impl.nodes;
24+
25+
import com.oracle.truffle.api.CompilerAsserts;
26+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
27+
import com.oracle.truffle.api.dsl.Cached;
28+
import com.oracle.truffle.api.dsl.Specialization;
29+
import com.oracle.truffle.api.library.CachedLibrary;
30+
import com.oracle.truffle.r.runtime.RInternalError;
31+
import com.oracle.truffle.r.runtime.data.RDataFactory;
32+
import com.oracle.truffle.r.runtime.data.RIntVector;
33+
import com.oracle.truffle.r.runtime.data.VectorDataLibrary;
34+
import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
35+
import com.oracle.truffle.r.runtime.data.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode;
36+
import com.oracle.truffle.r.runtime.gnur.SEXPTYPE;
37+
38+
public abstract class RfAllocArrayNode extends FFIUpCallNode.Arg2 {
39+
public static RfAllocArrayNode create() {
40+
return RfAllocArrayNodeGen.create();
41+
}
42+
43+
@Specialization(guards = "mode == type.code", limit = "getGenericDataLibraryCacheSize()")
44+
protected static Object allocArrayCached(@SuppressWarnings("unused") int mode, RIntVector dims,
45+
@Cached(value = "getType(mode)", allowUncached = true) SEXPTYPE type,
46+
@CachedLibrary("dims.getData()") VectorDataLibrary dimsDataLib,
47+
@Cached SetDimAttributeNode setDimNode) {
48+
CompilerAsserts.compilationConstant(type);
49+
return allocArray(dims, dimsDataLib, type, setDimNode);
50+
}
51+
52+
@Specialization(replaces = "allocArrayCached")
53+
@TruffleBoundary
54+
protected static Object allocArrayUncached(int mode, RIntVector dims, @Cached SetDimAttributeNode setDimNode) {
55+
return allocArray(dims, VectorDataLibrary.getFactory().getUncached(), getType(mode), setDimNode);
56+
}
57+
58+
private static Object allocArray(RIntVector dims, VectorDataLibrary dimsDataLib, SEXPTYPE type, SetDimAttributeNode setDimNode) {
59+
Object dimsData = dims.getData();
60+
int dimsLen = dimsDataLib.getLength(dimsData);
61+
int[] newDims = new int[dimsLen];
62+
int totalLen = 1;
63+
for (int i = 0; i < dimsLen; i++) {
64+
int dimLen = dimsDataLib.getIntAt(dimsData, i);
65+
newDims[i] = dimLen;
66+
totalLen *= dimLen;
67+
}
68+
Object array = RDataFactory.createEmptyVectorFromSEXPType(type, totalLen);
69+
if (!(array instanceof RAbstractContainer)) {
70+
throw RInternalError.shouldNotReachHere("Type not implemented for Rf_allocArray");
71+
} else {
72+
setDimNode.setDimensions((RAbstractContainer) array, newDims);
73+
return array;
74+
}
75+
}
76+
77+
protected static SEXPTYPE getType(int mode) {
78+
return SEXPTYPE.mapInt(mode);
79+
}
80+
}

com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/RfAllocVectorNode.java

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@
2222
*/
2323
package com.oracle.truffle.r.ffi.impl.nodes;
2424

25-
import static com.oracle.truffle.r.ffi.impl.common.RFFIUtils.unimplemented;
26-
27-
import java.util.Arrays;
28-
2925
import com.oracle.truffle.api.CompilerAsserts;
3026
import com.oracle.truffle.api.CompilerDirectives;
3127
import com.oracle.truffle.api.dsl.Cached;
@@ -34,7 +30,6 @@
3430
import com.oracle.truffle.r.runtime.RError;
3531
import com.oracle.truffle.r.runtime.RError.Message;
3632
import com.oracle.truffle.r.runtime.data.RDataFactory;
37-
import com.oracle.truffle.r.runtime.data.RNull;
3833
import com.oracle.truffle.r.runtime.gnur.SEXPTYPE;
3934

4035
@GenerateUncached
@@ -69,33 +64,7 @@ protected static Object doIt(@SuppressWarnings("unused") int mode, long n,
6964
}
7065
}
7166

72-
private static Object allocate(@Cached(value = "getType(mode)", allowUncached = true) SEXPTYPE type, int ni) {
73-
switch (type) {
74-
case INTSXP:
75-
return RDataFactory.createIntVector(new int[ni], RDataFactory.COMPLETE_VECTOR);
76-
case REALSXP:
77-
return RDataFactory.createDoubleVector(new double[ni], RDataFactory.COMPLETE_VECTOR);
78-
case LGLSXP:
79-
return RDataFactory.createLogicalVector(new byte[ni], RDataFactory.COMPLETE_VECTOR);
80-
case STRSXP:
81-
// fill list with empty strings
82-
String[] data = new String[ni];
83-
Arrays.fill(data, "");
84-
return RDataFactory.createStringVector(data, RDataFactory.COMPLETE_VECTOR);
85-
case CPLXSXP:
86-
return RDataFactory.createComplexVector(new double[2 * ni], RDataFactory.COMPLETE_VECTOR);
87-
case RAWSXP:
88-
return RDataFactory.createRawVector(new byte[ni]);
89-
case VECSXP:
90-
return RDataFactory.createList(ni);
91-
case LISTSXP:
92-
case LANGSXP:
93-
return RDataFactory.createPairList(ni, type);
94-
case NILSXP:
95-
return RNull.instance;
96-
default:
97-
CompilerDirectives.transferToInterpreter();
98-
throw unimplemented("unexpected SEXPTYPE " + type);
99-
}
67+
private static Object allocate(SEXPTYPE type, int ni) {
68+
return RDataFactory.createEmptyVectorFromSEXPType(type, ni);
10069
}
10170
}

com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/SetStringEltNode.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424

2525
import com.oracle.truffle.api.dsl.GenerateUncached;
2626
import com.oracle.truffle.api.dsl.Specialization;
27+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
2728
import com.oracle.truffle.api.library.CachedLibrary;
29+
import com.oracle.truffle.r.runtime.RInternalError;
2830
import com.oracle.truffle.r.runtime.data.CharSXPWrapper;
2931
import com.oracle.truffle.r.runtime.data.RStringVector;
3032
import com.oracle.truffle.r.runtime.data.VectorDataLibrary;
@@ -35,10 +37,17 @@ public static SetStringEltNode create() {
3537
return SetStringEltNodeGen.create();
3638
}
3739

38-
@Specialization(limit = "getTypedVectorDataLibraryCacheSize()")
40+
@Specialization
3941
Object doIt(RStringVector vector, long index, CharSXPWrapper element,
40-
@CachedLibrary("vector.getData()") VectorDataLibrary dataLibrary) {
41-
dataLibrary.setStringAt(vector.getData(), (int) index, element.getContents());
42+
@CachedLibrary(limit = "getTypedVectorDataLibraryCacheSize()") VectorDataLibrary dataLibrary) {
43+
Object newCharSXPData = null;
44+
try {
45+
newCharSXPData = dataLibrary.materializeCharSXPStorage(vector.getData());
46+
} catch (UnsupportedMessageException e) {
47+
throw RInternalError.shouldNotReachHere(e);
48+
}
49+
vector.setData(newCharSXPData);
50+
dataLibrary.setCharSXPAt(vector.getData(), (int) index, element);
4251
return null;
4352
}
4453
}

com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/StringEltNode.java

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -22,11 +22,13 @@
2222
*/
2323
package com.oracle.truffle.r.ffi.impl.nodes;
2424

25-
import com.oracle.truffle.api.dsl.Cached;
25+
import com.oracle.truffle.api.CompilerDirectives;
2626
import com.oracle.truffle.api.dsl.GenerateUncached;
2727
import com.oracle.truffle.api.dsl.Specialization;
28+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
2829
import com.oracle.truffle.api.library.CachedLibrary;
29-
import com.oracle.truffle.api.profiles.ConditionProfile;
30+
import com.oracle.truffle.r.runtime.RError;
31+
import com.oracle.truffle.r.runtime.RInternalError;
3032
import com.oracle.truffle.r.runtime.data.RStringVector;
3133
import com.oracle.truffle.r.runtime.data.VectorDataLibrary;
3234

@@ -36,17 +38,21 @@ public static StringEltNode create() {
3638
return StringEltNodeGen.create();
3739
}
3840

39-
// TODO: Make just one specialization that handles both altrep and non-altrep via
40-
// VectorDataLibrary
4141
@Specialization(limit = "1")
4242
Object doStringVector(RStringVector stringVector, long index,
43-
@CachedLibrary("stringVector.getData()") VectorDataLibrary dataLibrary,
44-
@Cached("createBinaryProfile()") ConditionProfile isAltrepProfile) {
45-
if (isAltrepProfile.profile(stringVector.isAltRep())) {
46-
return dataLibrary.getStringAt(stringVector, (int) index);
47-
} else {
48-
stringVector.wrapStrings();
49-
return stringVector.getWrappedDataAt((int) index);
43+
@CachedLibrary(limit = "getTypedVectorDataLibraryCacheSize()") VectorDataLibrary genericDataLib,
44+
@CachedLibrary("stringVector.getData()") VectorDataLibrary stringVecDataLib) {
45+
Object newCharSXPData = null;
46+
try {
47+
newCharSXPData = stringVecDataLib.materializeCharSXPStorage(stringVector.getData());
48+
} catch (UnsupportedMessageException e) {
49+
throw RInternalError.shouldNotReachHere(e);
5050
}
51+
stringVector.setData(newCharSXPData);
52+
if (index > Integer.MAX_VALUE) {
53+
CompilerDirectives.transferToInterpreter();
54+
throw RError.error(RError.NO_CALLER, RError.Message.LONG_VECTORS_NOT_SUPPORTED);
55+
}
56+
return genericDataLib.getCharSXPAt(stringVector.getData(), (int) index);
5157
}
5258
}

com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
import com.oracle.truffle.r.ffi.impl.nodes.RandFunctionsNodes;
9595
import com.oracle.truffle.r.ffi.impl.nodes.RawGetRegionNode;
9696
import com.oracle.truffle.r.ffi.impl.nodes.RealGetRegionNode;
97+
import com.oracle.truffle.r.ffi.impl.nodes.RfAllocArrayNode;
9798
import com.oracle.truffle.r.ffi.impl.nodes.RfAllocVectorNode;
9899
import com.oracle.truffle.r.ffi.impl.nodes.RfEvalNode;
99100
import com.oracle.truffle.r.ffi.impl.nodes.RfFindFun;
@@ -283,6 +284,7 @@ public interface StdUpCallsRFFI {
283284
Object Rf_allocVector(int mode, long n);
284285

285286
@RFFIRunGC
287+
@RFFIUpCallNode(value = RfAllocArrayNode.class, needsCallTarget = true)
286288
Object Rf_allocArray(int mode, Object dimsObj);
287289

288290
@RFFIRunGC

com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RFFIUpCallTargets.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,6 @@ public final class RFFIUpCallTargets {
8888
public volatile RootCallTarget AsS4;
8989

9090
public volatile RootCallTarget Match5UpCallNode;
91+
92+
public volatile RootCallTarget RfAllocArrayNode;
9193
}

com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/NativeDataAccess.java

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -1121,34 +1121,8 @@ static int getDataLength(RStringVector vector, Object[] data) {
11211121
}
11221122
}
11231123

1124-
static String getData(RStringVector vector, Object data, int index) {
1125-
if (noStringNative.isValid() || data != null) {
1126-
Object localData = data;
1127-
if (localData instanceof String[]) {
1128-
return ((String[]) localData)[index];
1129-
}
1130-
assert data instanceof CharSXPWrapper[] : localData;
1131-
assert ((CharSXPWrapper[]) localData)[index] != null;
1132-
return ((CharSXPWrapper[]) localData)[index].getContents();
1133-
} else {
1134-
return getStringNativeMirrorData(vector.getNativeMirror(), index).getContents();
1135-
}
1136-
}
1137-
1138-
static void setData(RStringVector vector, Object data, int index, String value) {
1139-
assert data != null;
1140-
if (data instanceof String[]) {
1141-
assert !vector.isNativized();
1142-
((String[]) data)[index] = value;
1143-
} else {
1144-
assert data instanceof CharSXPWrapper[] : data;
1145-
CharSXPWrapper elem = CharSXPWrapper.create(value);
1146-
((CharSXPWrapper[]) data)[index] = elem;
1147-
1148-
if (!noStringNative.isValid() && vector.isNativized()) {
1149-
NativeDataAccess.setNativeMirrorStringData(vector.getNativeMirror(), index, elem);
1150-
}
1151-
}
1124+
static CharSXPWrapper getData(RStringVector vector, int index) {
1125+
return getStringNativeMirrorData(vector.getNativeMirror(), index);
11521126
}
11531127

11541128
static void setData(RStringVector vector, CharSXPWrapper[] data, int index, CharSXPWrapper value) {

0 commit comments

Comments
 (0)