Skip to content

Commit c3665c8

Browse files
committed
Implement C function match5, which is not exported API, but still used by some packages
1 parent 2a1e5b3 commit c3665c8

File tree

11 files changed

+190
-168
lines changed

11 files changed

+190
-168
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ New features:
1313

1414
# 20.2.0
1515

16+
Added missing R builtins and C APIs:
17+
18+
* non-API C function match5, which is used by some packages
19+
* non-API C function `match5`, which is used by some packages (#149)
20+
* define dummy `XLENGTH` macro if `USE_RINTERNALS` is defined
21+
* non-existence of this macro is used by some packages to detect old R versions
22+
* `IS_LONG_VEC` C API function
23+
1624
Bug fixes:
1725

1826
* FastR cleans-up the temporary directory created for internal implementation of the R input handlers

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2697,7 +2697,7 @@ public Object Rf_asCharacterFactor(Object x) {
26972697
}
26982698

26992699
@Override
2700-
public Object Rf_match(Object itables, Object ix, int nmatch) {
2700+
public Object match5(Object itables, Object ix, int nmatch, Object incomparables, Object env) {
27012701
throw implementedAsNode();
27022702
}
27032703

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

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,44 +22,31 @@
2222
*/
2323
package com.oracle.truffle.r.ffi.impl.nodes;
2424

25-
import com.oracle.truffle.api.CompilerDirectives;
25+
import com.oracle.truffle.api.dsl.Cached;
2626
import com.oracle.truffle.api.dsl.Fallback;
2727
import com.oracle.truffle.api.dsl.GenerateUncached;
2828
import com.oracle.truffle.api.dsl.Specialization;
2929
import com.oracle.truffle.api.dsl.TypeSystemReference;
3030
import com.oracle.truffle.r.ffi.impl.nodes.MatchNodesFactory.NonNullStringMatchNodeGen;
31-
import com.oracle.truffle.r.nodes.builtin.MatchInternalNode;
32-
import com.oracle.truffle.r.nodes.builtin.MatchInternalNodeGen;
33-
import com.oracle.truffle.r.runtime.RError;
34-
import static com.oracle.truffle.r.runtime.RError.Message.MATCH_VECTOR_ARGS;
31+
import com.oracle.truffle.r.nodes.builtin.Match5Node;
3532
import com.oracle.truffle.r.runtime.RInternalError;
3633
import com.oracle.truffle.r.runtime.RRuntime;
3734
import com.oracle.truffle.r.runtime.data.CharSXPWrapper;
3835
import com.oracle.truffle.r.runtime.data.RTypes;
3936
import com.oracle.truffle.r.runtime.data.RStringVector;
40-
import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
4137

4238
public final class MatchNodes {
4339

4440
@TypeSystemReference(RTypes.class)
45-
public abstract static class MatchNode extends FFIUpCallNode.Arg3 {
46-
47-
@Child MatchInternalNode match = MatchInternalNodeGen.create();
48-
41+
public abstract static class Match5UpCallNode extends FFIUpCallNode.Arg5 {
4942
@Specialization
50-
Object match(RAbstractVector x, RAbstractVector table, int noMatch) {
51-
return match.execute(x, table, noMatch);
52-
}
53-
54-
@SuppressWarnings("unused")
55-
@Fallback
56-
Object match(Object itables, Object ix, Object nmatch) {
57-
CompilerDirectives.transferToInterpreter();
58-
throw RError.error(this, MATCH_VECTOR_ARGS);
43+
Object match(Object x, Object table, int noMatch, Object incomparables, @SuppressWarnings("unused") Object env,
44+
@Cached Match5Node match5Node) {
45+
return match5Node.execute(x, table, noMatch, incomparables);
5946
}
6047

61-
public static MatchNode create() {
62-
return MatchNodesFactory.MatchNodeGen.create();
48+
public static Match5UpCallNode create() {
49+
return MatchNodesFactory.Match5UpCallNodeGen.create();
6350
}
6451
}
6552

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,8 +1034,12 @@ public interface StdUpCallsRFFI {
10341034
@RFFIUpCallNode(value = AsCharacterFactor.class, needsCallTarget = true)
10351035
Object Rf_asCharacterFactor(Object x);
10361036

1037-
@RFFIUpCallNode(value = MatchNodes.MatchNode.class, needsCallTarget = true)
1038-
Object Rf_match(Object itables, Object ix, int nmatch);
1037+
/**
1038+
* The {@code match5} function is internal to R, but nonetheless referenced by some R packages.
1039+
* Moreover, other {@code Rf_match} variants delegate to this function.
1040+
*/
1041+
@RFFIUpCallNode(value = MatchNodes.Match5UpCallNode.class, needsCallTarget = true)
1042+
Object match5(Object itables, Object ix, int nmatch, Object incomparables, Object env);
10391043

10401044
@RFFIUpCallNode(MatchNodes.NonNullStringMatchNode.class)
10411045
boolean Rf_NonNullStringMatch(Object s, Object t);

com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ typedef double (*call_Rf_ftrunc)(double a);
426426
typedef double (*call_Rf_cospi)(double a);
427427
typedef double (*call_Rf_sinpi)(double a);
428428
typedef double (*call_Rf_tanpi)(double a);
429-
typedef SEXP (*call_Rf_match)(SEXP itable, SEXP ix, int nmatch);
429+
typedef SEXP (*call_match5)(SEXP itable, SEXP ix, int nmatch, SEXP incomparables, SEXP env);
430430
typedef Rboolean (*call_Rf_NonNullStringMatch)(SEXP s, SEXP t);
431431
typedef SEXP (*call_getvar)();
432432
typedef SEXP (*call_R_ParseVector)(SEXP text, int n, SEXP srcFile);

com.oracle.truffle.r.native/fficall/src/truffle_common/match.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,17 @@ Rboolean Rf_NonNullStringMatch(SEXP s, SEXP t)
2828
return ((call_Rf_NonNullStringMatch) callbacks[Rf_NonNullStringMatch_x])(s, t);
2929
}
3030

31+
SEXP Rf_matchE(SEXP itable, SEXP ix, int nmatch, SEXP env)
32+
{
33+
return ((call_match5) callbacks[match5_x])(itable, ix, nmatch, NULL, env);
34+
}
35+
36+
SEXP Rf_match(SEXP itable, SEXP ix, int nmatch)
37+
{
38+
return ((call_match5) callbacks[match5_x])(itable, ix, nmatch, NULL, R_BaseEnv);
39+
}
40+
41+
SEXP match5(SEXP itable, SEXP ix, int nmatch, SEXP incomparables, SEXP env)
42+
{
43+
return ((call_match5) callbacks[match5_x])(itable, ix, nmatch, incomparables, env);
44+
}

com.oracle.truffle.r.native/fficall/src/truffle_common/unique.c

Lines changed: 0 additions & 36 deletions
This file was deleted.

com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Match.java

Lines changed: 4 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -24,31 +24,15 @@
2424

2525
import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.logicalFalse;
2626
import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.logicalValue;
27-
import static com.oracle.truffle.r.runtime.RError.Message.MATCH_VECTOR_ARGS;
2827
import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
2928
import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
3029

31-
import java.util.Arrays;
32-
3330
import com.oracle.truffle.api.dsl.Cached;
34-
import com.oracle.truffle.api.dsl.Fallback;
3531
import com.oracle.truffle.api.dsl.Specialization;
36-
import com.oracle.truffle.api.profiles.ConditionProfile;
37-
import com.oracle.truffle.r.nodes.builtin.MatchInternalNode;
32+
import com.oracle.truffle.r.nodes.builtin.Match5Node;
3833
import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
39-
import com.oracle.truffle.r.nodes.helpers.InheritsCheckNode;
40-
import com.oracle.truffle.r.nodes.helpers.RFactorNodes;
41-
import com.oracle.truffle.r.nodes.unary.CastStringNode;
4234
import com.oracle.truffle.r.runtime.RError.Message;
43-
import com.oracle.truffle.r.runtime.RRuntime;
44-
import com.oracle.truffle.r.runtime.RType;
4535
import com.oracle.truffle.r.runtime.builtins.RBuiltin;
46-
import com.oracle.truffle.r.runtime.data.RDataFactory;
47-
import com.oracle.truffle.r.runtime.data.RNull;
48-
import com.oracle.truffle.r.runtime.data.closures.RClosures;
49-
import com.oracle.truffle.r.runtime.data.RIntVector;
50-
import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
51-
import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
5236

5337
/*
5438
* TODO: handle "incomparables" parameter.
@@ -60,97 +44,14 @@ public abstract class Match extends RBuiltinNode.Arg4 {
6044

6145
static {
6246
Casts casts = new Casts(Match.class);
63-
// TODO initially commented out because of use of scalars, the commented out version
64-
// converted to new cast pipelines API
65-
66-
// casts.arg("x").allowNull().mustBe(abstractVectorValue(), SHOW_CALLER,
67-
// MATCH_VECTOR_ARGS).asVectorPreserveAttrs(true);
68-
// casts.arg("table").allowNull().mustBe(abstractVectorValue()).asVectorPreserveAttrs(true);
6947
casts.arg("nomatch").asIntegerVector().findFirst();
7048
casts.arg("incomparables").defaultError(Message.GENERIC, "usage of 'incomparables' in match not implemented").allowNull().mustBe(logicalValue()).asLogicalVector().findFirst().mustBe(
7149
logicalFalse());
7250
}
7351

74-
protected boolean isCharSXP(RAbstractListVector list) {
75-
for (int i = 0; i < list.getLength(); i++) {
76-
if (!(RType.getRType(list.getDataAt(i)).equals(RType.Char))) {
77-
return false;
78-
}
79-
}
80-
return true;
81-
}
82-
83-
@Specialization
84-
@SuppressWarnings("unused")
85-
protected RIntVector match(RNull x, RNull table, int nomatch, Object incomparables) {
86-
return RDataFactory.createIntVector(0);
87-
}
88-
8952
@Specialization
90-
@SuppressWarnings("unused")
91-
protected RIntVector match(RNull x, RAbstractVector table, int nomatch, Object incomparables) {
92-
return RDataFactory.createIntVector(0);
93-
}
94-
95-
@Specialization
96-
@SuppressWarnings("unused")
97-
protected RIntVector match(RAbstractVector x, RNull table, int nomatch, Object incomparables,
98-
@Cached("createBinaryProfile()") ConditionProfile na) {
99-
int[] data = new int[x.getLength()];
100-
Arrays.fill(data, nomatch);
101-
return RDataFactory.createIntVector(data, na.profile(!RRuntime.isNA(nomatch)));
102-
}
103-
104-
@Child private InheritsCheckNode factorInheritsCheck = InheritsCheckNode.create(RRuntime.CLASS_FACTOR);
105-
106-
protected boolean isFactor(Object o) {
107-
return factorInheritsCheck.execute(o);
108-
}
109-
110-
@Specialization(guards = {"isFactor(x)", "isFactor(table)"})
111-
protected Object matchFactor(RIntVector x, RIntVector table, int nomatch, @SuppressWarnings("unused") Object incomparables,
112-
@Cached("create()") RFactorNodes.GetLevels getLevelsNode,
113-
@Cached() MatchInternalNode match) {
114-
return match.execute(RClosures.createFactorToVector(x, true, getLevelsNode.execute(x)),
115-
RClosures.createFactorToVector(table, true, getLevelsNode.execute(table)), nomatch);
116-
}
117-
118-
@Specialization(guards = {"isFactor(x)", "!isFactor(table)"})
119-
protected Object matchFactor(RIntVector x, RAbstractVector table, int nomatch, @SuppressWarnings("unused") Object incomparables,
120-
@Cached("create()") RFactorNodes.GetLevels getLevelsNode,
121-
@Cached() MatchInternalNode match) {
122-
return match.execute(RClosures.createFactorToVector(x, true, getLevelsNode.execute(x)), table, nomatch);
123-
}
124-
125-
@Specialization(guards = {"!isFactor(x)", "isFactor(table)"})
126-
protected Object matchFactor(RAbstractVector x, RIntVector table, int nomatch, @SuppressWarnings("unused") Object incomparables,
127-
@Cached("create()") RFactorNodes.GetLevels getLevelsNode,
128-
@Cached() MatchInternalNode match) {
129-
return match.execute(x, RClosures.createFactorToVector(table, true, getLevelsNode.execute(table)), nomatch);
130-
}
131-
132-
@Specialization(guards = {"isCharSXP(x)", "isCharSXP(table)"})
133-
protected Object matchDoubleList(RAbstractListVector x, RAbstractListVector table, int nomatchObj, @SuppressWarnings("unused") Object incomparables,
134-
@Cached() MatchInternalNode match) {
135-
return match.execute(x, table, nomatchObj);
136-
}
137-
138-
@Specialization(guards = {"!isRIntVector(table) || !isFactor(table)"})
139-
protected Object matchList(RAbstractListVector x, RAbstractVector table, int nomatchObj, @SuppressWarnings("unused") Object incomparables,
140-
@Cached("create()") CastStringNode cast,
141-
@Cached() MatchInternalNode match) {
142-
return match.execute((RAbstractVector) cast.doCast(x), table, nomatchObj);
143-
}
144-
145-
@Specialization(guards = {"!isRAbstractListVector(x)", "!isRIntVector(x) || !isFactor(x)", "!isRIntVector(table) || !isFactor(table)"})
146-
protected Object match(RAbstractVector x, RAbstractVector table, int noMatch, @SuppressWarnings("unused") Object incomparables,
147-
@Cached() MatchInternalNode match) {
148-
return match.execute(x, table, noMatch);
149-
}
150-
151-
@Fallback
152-
@SuppressWarnings("unused")
153-
protected RIntVector match(Object x, Object table, Object nomatch, Object incomparables) {
154-
throw error(MATCH_VECTOR_ARGS);
53+
Object doIt(Object x, Object table, int nomatch, Object incomparables,
54+
@Cached Match5Node match5Node) {
55+
return match5Node.execute(x, table, nomatch, incomparables);
15556
}
15657
}

0 commit comments

Comments
 (0)