Skip to content

Commit 2676cbe

Browse files
committed
[GR-9802] Implemented the RTypeValue interface for CharSXPWrapper.
PullRequest: fastr/1754
2 parents de00a17 + 8a8c07c commit 2676cbe

File tree

20 files changed

+331
-23
lines changed

20 files changed

+331
-23
lines changed

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

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -582,13 +582,6 @@ public int LEVELS(Object x) {
582582
if (x instanceof RTypedValue) {
583583
int gpBits = ((RTypedValue) x).getGPBits();
584584
return gpBits;
585-
} else if (x instanceof CharSXPWrapper) {
586-
// TODO returning ASCII_MASK works for data.table,
587-
// but properly CharSXPWrapper has to implement RTypedValue ...
588-
// see also CHARSXP charset bits in include/Defn.h
589-
// #define ASCII_MASK (1<<6)
590-
// return 1 << 6;
591-
throw RInternalError.shouldNotReachHere("Not yet implemented - CharSXPWrapper has to implement RTypedValue!");
592585
}
593586
throw RInternalError.shouldNotReachHere();
594587
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
import com.oracle.truffle.r.runtime.RError;
6969
import com.oracle.truffle.r.runtime.RRuntime;
7070
import com.oracle.truffle.r.runtime.builtins.RBuiltin;
71+
import com.oracle.truffle.r.runtime.data.CharSXPWrapper;
7172
import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
7273
import com.oracle.truffle.r.runtime.data.RAttributesLayout;
7374
import com.oracle.truffle.r.runtime.data.RDataFactory;
@@ -127,6 +128,7 @@ protected boolean isSimpleArguments(RArgsValuesAndNames args) {
127128
!(args.getArgument(0) instanceof RPairList) &&
128129
!(args.getArgument(0) instanceof RSymbol) &&
129130
!(args.getArgument(0) instanceof RS4Object) &&
131+
!(args.getArgument(0) instanceof CharSXPWrapper) &&
130132
!RRuntime.isForeignObject(args.getArgument(0));
131133
}
132134

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import com.oracle.truffle.r.runtime.RInternalError;
4343
import com.oracle.truffle.r.runtime.RRuntime;
4444
import com.oracle.truffle.r.runtime.builtins.RBuiltin;
45+
import com.oracle.truffle.r.runtime.data.CharSXPWrapper;
4546
import com.oracle.truffle.r.runtime.data.RAttributable;
4647
import com.oracle.truffle.r.runtime.data.RAttributesLayout;
4748
import com.oracle.truffle.r.runtime.data.RExternalPtr;
@@ -147,6 +148,13 @@ protected byte doInternalIdentical(String x, String y, boolean numEq, boolean si
147148
return RRuntime.asLogical(x.equals(y));
148149
}
149150

151+
@SuppressWarnings("unused")
152+
@Specialization
153+
protected byte doInternalIdentical(CharSXPWrapper x, CharSXPWrapper y, boolean numEq, boolean singleNA, boolean attribAsSet, boolean ignoreBytecode, boolean ignoreEnvironment,
154+
boolean ignoreSrcref) {
155+
return RRuntime.asLogical(x.equals(y));
156+
}
157+
150158
@SuppressWarnings("unused")
151159
@Specialization
152160
protected byte doInternalIdentical(double x, double y, boolean numEq, boolean singleNA, boolean attribAsSet, boolean ignoreBytecode, boolean ignoreEnvironment, boolean ignoreSrcref) {

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

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@
2222
*/
2323
package com.oracle.truffle.r.nodes.builtin.base;
2424

25+
import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.constant;
26+
import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.missingValue;
27+
import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue;
28+
import static com.oracle.truffle.r.runtime.RVisibility.OFF;
29+
import static com.oracle.truffle.r.runtime.builtins.RBehavior.IO;
30+
import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
31+
32+
import java.io.IOException;
33+
2534
import com.oracle.truffle.api.CompilerDirectives;
2635
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
2736
import com.oracle.truffle.api.dsl.Specialization;
@@ -30,28 +39,23 @@
3039
import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions;
3140
import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
3241
import com.oracle.truffle.r.nodes.builtin.casts.fluent.CastNodeBuilder;
33-
import com.oracle.truffle.r.runtime.builtins.RBuiltin;
34-
import com.oracle.truffle.r.runtime.gnur.SEXPTYPE;
3542
import com.oracle.truffle.r.nodes.unary.CastNode;
43+
import com.oracle.truffle.r.runtime.RError;
44+
import com.oracle.truffle.r.runtime.RRuntime;
45+
import com.oracle.truffle.r.runtime.builtins.RBuiltin;
46+
import com.oracle.truffle.r.runtime.conn.StdConnections;
47+
import com.oracle.truffle.r.runtime.data.CharSXPWrapper;
3648
import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
3749
import com.oracle.truffle.r.runtime.data.RAttributable;
3850
import com.oracle.truffle.r.runtime.data.RListBase;
3951
import com.oracle.truffle.r.runtime.data.RPairList;
52+
import com.oracle.truffle.r.runtime.data.RRaw;
4053
import com.oracle.truffle.r.runtime.data.RSharingAttributeStorage;
54+
import com.oracle.truffle.r.runtime.data.RTypedValue;
4155
import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
4256
import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
4357
import com.oracle.truffle.r.runtime.env.REnvironment;
44-
import com.oracle.truffle.r.runtime.RRuntime;
45-
import com.oracle.truffle.r.runtime.RError;
46-
import com.oracle.truffle.r.runtime.conn.StdConnections;
47-
import com.oracle.truffle.r.runtime.data.RRaw;
48-
import java.io.IOException;
49-
import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.constant;
50-
import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.missingValue;
51-
import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue;
52-
import static com.oracle.truffle.r.runtime.RVisibility.OFF;
53-
import static com.oracle.truffle.r.runtime.builtins.RBehavior.IO;
54-
import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
58+
import com.oracle.truffle.r.runtime.gnur.SEXPTYPE;
5559

5660
/**
5761
* Internal inspect builtin.
@@ -124,6 +128,24 @@ private void inspectTree(StringBuilder sb, int indent, String label, Object obj,
124128
sb.append("] ");
125129
if (obj instanceof String) {
126130
sb.append('"').append(obj).append("\"\n");
131+
} else if (obj instanceof CharSXPWrapper) {
132+
int typeinfo = ((CharSXPWrapper) obj).getTypedValueInfo();
133+
if (typeinfo == RTypedValue.BYTES_MASK) {
134+
sb.append("[bytes] ");
135+
}
136+
if (typeinfo == RTypedValue.LATIN1_MASK) {
137+
sb.append("[latin1] ");
138+
}
139+
if (typeinfo == RTypedValue.UTF8_MASK) {
140+
sb.append("[UTF8] ");
141+
}
142+
if (typeinfo == RTypedValue.CACHED_MASK) {
143+
sb.append("[cached] ");
144+
}
145+
if (typeinfo == RTypedValue.ASCII_MASK) {
146+
sb.append("[ASCII] ");
147+
}
148+
sb.append('"').append(((CharSXPWrapper) obj).getContents()).append("\"\n");
127149
} else if (obj instanceof Double) {
128150
// GNU R uses Rprintf("%g",val) but String.format("%g", val) differs
129151
sb.append(obj);

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import com.oracle.truffle.r.runtime.DSLConfig;
4646
import com.oracle.truffle.r.runtime.RError.Message;
4747
import com.oracle.truffle.r.runtime.RRuntime;
48+
import com.oracle.truffle.r.runtime.RType;
4849
import com.oracle.truffle.r.runtime.builtins.RBuiltin;
4950
import com.oracle.truffle.r.runtime.data.RDataFactory;
5051
import com.oracle.truffle.r.runtime.data.RIntVector;
@@ -79,6 +80,15 @@ protected static ProfiledMatchInternalNode createInternal() {
7980
return ProfiledMatchInternalNodeGen.create();
8081
}
8182

83+
protected boolean isCharSXP(RAbstractListVector list) {
84+
for (int i = 0; i < list.getLength(); i++) {
85+
if (!(RType.getRType(list.getDataAt(i)).equals(RType.Char))) {
86+
return false;
87+
}
88+
}
89+
return true;
90+
}
91+
8292
@Specialization
8393
@SuppressWarnings("unused")
8494
protected RIntVector match(RNull x, RNull table, int nomatch, Object incomparables) {
@@ -128,6 +138,12 @@ protected Object matchFactor(RAbstractVector x, RAbstractIntVector table, int no
128138
return match.execute(x, RClosures.createFactorToVector(table, true, getLevelsNode.execute(table)), nomatch);
129139
}
130140

141+
@Specialization(guards = {"isCharSXP(x)", "isCharSXP(table)"})
142+
protected Object matchDoubleList(RAbstractListVector x, RAbstractListVector table, int nomatchObj, @SuppressWarnings("unused") Object incomparables,
143+
@Cached("createInternal()") ProfiledMatchInternalNode match) {
144+
return match.execute(x, table, nomatchObj);
145+
}
146+
131147
@Specialization(guards = {"!isRAbstractIntVector(table) || !isFactor(table)"})
132148
protected Object matchList(RAbstractListVector x, RAbstractVector table, int nomatchObj, @SuppressWarnings("unused") Object incomparables,
133149
@Cached("create()") CastStringNode cast,
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright (c) 2018, 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+
24+
package com.oracle.truffle.r.nodes.builtin.base.printer;
25+
26+
import java.io.IOException;
27+
28+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
29+
import com.oracle.truffle.r.runtime.RDeparse;
30+
import com.oracle.truffle.r.runtime.data.CharSXPWrapper;
31+
32+
final class CharSXPPrinter extends AbstractValuePrinter<CharSXPWrapper> {
33+
34+
static final com.oracle.truffle.r.nodes.builtin.base.printer.CharSXPPrinter INSTANCE = new com.oracle.truffle.r.nodes.builtin.base.printer.CharSXPPrinter();
35+
36+
private CharSXPPrinter() {
37+
// singleton
38+
}
39+
40+
@Override
41+
@TruffleBoundary
42+
protected void printValue(CharSXPWrapper value, PrintContext printCtx) throws IOException {
43+
printCtx.output().print(RDeparse.deparse(value, RDeparse.DEFAULT_CUTOFF, true, RDeparse.SIMPLEDEPARSE, -1));
44+
}
45+
}

com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinters.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.oracle.truffle.r.nodes.function.ClassHierarchyNode;
3232
import com.oracle.truffle.r.runtime.RInternalError;
3333
import com.oracle.truffle.r.runtime.RRuntime;
34+
import com.oracle.truffle.r.runtime.data.CharSXPWrapper;
3435
import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
3536
import com.oracle.truffle.r.runtime.data.RAttributable;
3637
import com.oracle.truffle.r.runtime.data.RExpression;
@@ -64,6 +65,7 @@ private ValuePrinters() {
6465
printers.put(RExpression.class, ExpressionPrinter.INSTANCE);
6566
printers.put(RExternalPtr.class, ExternalPtrPrinter.INSTANCE);
6667
printers.put(RS4Object.class, S4ObjectPrinter.INSTANCE);
68+
printers.put(CharSXPWrapper.class, CharSXPPrinter.INSTANCE);
6769
}
6870

6971
@SuppressWarnings({"rawtypes", "unchecked"})

com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BoxPrimitiveNode.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.oracle.truffle.api.dsl.Cached;
2626
import com.oracle.truffle.api.dsl.Specialization;
2727
import com.oracle.truffle.r.nodes.unary.CastNode;
28+
import com.oracle.truffle.r.runtime.data.CharSXPWrapper;
2829
import com.oracle.truffle.r.runtime.data.RDouble;
2930
import com.oracle.truffle.r.runtime.data.RInteger;
3031
import com.oracle.truffle.r.runtime.data.RLogical;
@@ -63,6 +64,11 @@ protected static RString doString(String value) {
6364
return RString.valueOf(value);
6465
}
6566

67+
@Specialization
68+
protected static CharSXPWrapper doCharSXPWrapper(CharSXPWrapper value) {
69+
return value;
70+
}
71+
6672
/*
6773
* For the limit we use the number of primitive specializations - 1. After that its better to
6874
* check !isPrimitive.

com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/MatchInternalNode.java

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
*/
2323
package com.oracle.truffle.r.nodes.builtin;
2424

25+
import java.util.Arrays;
26+
2527
import com.oracle.truffle.api.CompilerDirectives;
2628
import com.oracle.truffle.api.dsl.Cached;
2729
import com.oracle.truffle.api.dsl.Specialization;
@@ -32,22 +34,24 @@
3234
import com.oracle.truffle.r.nodes.unary.CastStringNodeGen;
3335
import com.oracle.truffle.r.runtime.RRuntime;
3436
import com.oracle.truffle.r.runtime.RType;
37+
import com.oracle.truffle.r.runtime.data.CharSXPWrapper;
3538
import com.oracle.truffle.r.runtime.data.RComplex;
3639
import com.oracle.truffle.r.runtime.data.RDataFactory;
3740
import com.oracle.truffle.r.runtime.data.RIntSequence;
3841
import com.oracle.truffle.r.runtime.data.RIntVector;
42+
import com.oracle.truffle.r.runtime.data.RList;
3943
import com.oracle.truffle.r.runtime.data.RSequence;
4044
import com.oracle.truffle.r.runtime.data.RStringSequence;
4145
import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector;
4246
import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
4347
import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
48+
import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
4449
import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
4550
import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector;
4651
import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
4752
import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
4853
import com.oracle.truffle.r.runtime.nodes.RBaseNode;
4954
import com.oracle.truffle.r.runtime.ops.na.NAProfile;
50-
import java.util.Arrays;
5155

5256
public abstract class MatchInternalNode extends RBaseNode {
5357

@@ -71,6 +75,15 @@ protected boolean isSequence(RAbstractVector vec) {
7175
return vec instanceof RSequence;
7276
}
7377

78+
protected boolean isCharSXP(RAbstractListVector list) {
79+
for (int i = 0; i < list.getLength(); i++) {
80+
if (!(RType.getRType(list.getDataAt(i)).equals(RType.Char))) {
81+
return false;
82+
}
83+
}
84+
return true;
85+
}
86+
7487
@Specialization
7588
@CompilerDirectives.TruffleBoundary
7689
protected RIntVector matchInSequence(RAbstractIntVector x, RIntSequence table, int nomatch) {
@@ -439,6 +452,86 @@ protected RIntVector match(RAbstractStringVector x, RAbstractStringVector table,
439452
return RDataFactory.createIntVector(result, setCompleteState(matchAll, nomatch));
440453
}
441454

455+
@Specialization(guards = {"x.getLength() == 1", "isCharSXP(x)", "isCharSXP(table)"})
456+
@CompilerDirectives.TruffleBoundary
457+
protected int matchSizeOne(RList x, RList table, int nomatch,
458+
@Cached("create()") NAProfile naProfile,
459+
@Cached("create()") BranchProfile foundProfile,
460+
@Cached("create()") BranchProfile notFoundProfile) {
461+
Object data = x.getDataAt(0);
462+
Object tableData;
463+
464+
assert data instanceof CharSXPWrapper;
465+
String element = ((CharSXPWrapper) data).getContents();
466+
int length = table.getLength();
467+
if (naProfile.isNA(element)) {
468+
for (int i = 0; i < length; i++) {
469+
tableData = table.getDataAt(i);
470+
assert tableData instanceof CharSXPWrapper;
471+
if (RRuntime.isNA(((CharSXPWrapper) tableData).getContents())) {
472+
foundProfile.enter();
473+
return i + 1;
474+
}
475+
}
476+
} else {
477+
for (int i = 0; i < length; i++) {
478+
tableData = table.getDataAt(i);
479+
assert tableData instanceof CharSXPWrapper;
480+
if (element.equals(((CharSXPWrapper) tableData).getContents())) {
481+
foundProfile.enter();
482+
return i + 1;
483+
}
484+
}
485+
}
486+
notFoundProfile.enter();
487+
return nomatch;
488+
}
489+
490+
@Specialization(guards = {"x.getLength() != 1", "isCharSXP(x)", "isCharSXP(table)"})
491+
@CompilerDirectives.TruffleBoundary
492+
protected RIntVector match(RList x, RList table, int nomatch) {
493+
int[] result = initResult(x.getLength(), nomatch);
494+
Object element;
495+
boolean matchAll = true;
496+
NonRecursiveHashMapCharacter hashTable;
497+
if (bigTableProfile.profile(table.getLength() > (x.getLength() * TABLE_SIZE_FACTOR))) {
498+
hashTable = new NonRecursiveHashMapCharacter(x.getLength());
499+
NonRecursiveHashSetCharacter hashSet = new NonRecursiveHashSetCharacter(x.getLength());
500+
for (int i = 0; i < result.length; i++) {
501+
element = x.getDataAt(i);
502+
assert element instanceof CharSXPWrapper;
503+
hashSet.add(((CharSXPWrapper) element).getContents());
504+
}
505+
for (int i = table.getLength() - 1; i >= 0; i--) {
506+
element = table.getDataAt(i);
507+
assert element instanceof CharSXPWrapper;
508+
String val = ((CharSXPWrapper) element).getContents();
509+
if (hashSet.contains(val)) {
510+
hashTable.put(val, i);
511+
}
512+
}
513+
} else {
514+
hashTable = new NonRecursiveHashMapCharacter(table.getLength());
515+
for (int i = table.getLength() - 1; i >= 0; i--) {
516+
element = table.getDataAt(i);
517+
assert element instanceof CharSXPWrapper;
518+
hashTable.put(((CharSXPWrapper) element).getContents(), i);
519+
}
520+
}
521+
for (int i = 0; i < result.length; i++) {
522+
element = x.getDataAt(i);
523+
assert element instanceof CharSXPWrapper;
524+
String xx = ((CharSXPWrapper) element).getContents();
525+
int index = hashTable.get(xx);
526+
if (index != -1) {
527+
result[i] = index + 1;
528+
} else {
529+
matchAll = false;
530+
}
531+
}
532+
return RDataFactory.createIntVector(result, setCompleteState(matchAll, nomatch));
533+
}
534+
442535
@Specialization
443536
protected RIntVector match(RAbstractDoubleVector x, RAbstractComplexVector table, int nomatch,
444537
@Cached("createBinaryProfile()") ConditionProfile isNAProfile) {

0 commit comments

Comments
 (0)