Skip to content

Commit 16e322a

Browse files
committed
[GR-14293] Additional native API functions.
PullRequest: fastr/1969
2 parents ed63f6d + abfad99 commit 16e322a

File tree

22 files changed

+565
-310
lines changed

22 files changed

+565
-310
lines changed

.gitignore

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,4 +147,12 @@ documentation/.pydevproject
147147
com.oracle.truffle.r.native/gnur/patch-build
148148
com.oracle.truffle.r.test.native/embedded/embedded.actual.output
149149
com.oracle.truffle.r.test.native/embedded/main.actual.output
150-
f2c
150+
f2c
151+
test.fastr
152+
test.gnur
153+
test.diffs
154+
install.tmp.fastr
155+
install.tmp.gnur
156+
lib.install.packages.fastr
157+
lib.install.packages.gnur
158+
/com.oracle.truffle.r.release/doc/

com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/TruffleRLanguageImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ protected String toString(RContext context, Object value) {
173173
stateStdConnections.setBuffer(buffer);
174174
RContext.getEngine().evalFunction((RFunction) printObj, callingFrame, RCaller.topLevel, false, ArgumentsSignature.empty(1), asVector);
175175
// remove the last "\n", which is useful for REPL, but not here
176-
if (buffer.charAt(buffer.length() - 1) == '\n') {
176+
if (buffer.length() > 0 && buffer.charAt(buffer.length() - 1) == '\n') {
177177
buffer.setLength(buffer.length() - 1);
178178
}
179179
return buffer.toString();

com.oracle.truffle.r.ffi.codegen/src/com/oracle/truffle/r/ffi/codegen/FFIUpCallsIndexCodeGen.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2019, 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
@@ -23,6 +23,7 @@
2323
package com.oracle.truffle.r.ffi.codegen;
2424

2525
import java.lang.reflect.Method;
26+
import java.util.ArrayList;
2627
import java.util.Arrays;
2728
import java.util.Comparator;
2829

@@ -47,19 +48,20 @@ private void run(String[] args) {
4748
out.append("#ifndef RFFI_UPCALLSINDEX_H\n");
4849
out.append("#define RFFI_UPCALLSINDEX_H\n");
4950
out.append('\n');
50-
Method[] methods = UpCallsRFFI.class.getMethods();
51-
Arrays.sort(methods, new Comparator<Method>() {
51+
ArrayList<Method> methods = new ArrayList<>(Arrays.asList(UpCallsRFFI.class.getMethods()));
52+
methods.removeAll(Arrays.asList(UpCallsRFFI.class.getDeclaredMethods()));
53+
methods.sort(new Comparator<Method>() {
5254
@Override
5355
public int compare(Method e1, Method e2) {
5456
return e1.getName().toString().compareTo(e2.getName().toString());
5557
}
5658
});
57-
for (int i = 0; i < methods.length; i++) {
58-
Method method = methods[i];
59+
for (int i = 0; i < methods.size(); i++) {
60+
Method method = methods.get(i);
5961
out.append("#define ").append(method.getName()).append("_x ").append(Integer.toString(i)).append('\n');
6062
}
6163
out.append('\n');
62-
out.append("#define ").append("UPCALLS_TABLE_SIZE ").append(Integer.toString(methods.length)).append('\n');
64+
out.append("#define ").append("UPCALLS_TABLE_SIZE ").append(Integer.toString(methods.size())).append('\n');
6365
out.append('\n');
6466
out.append("#endif // RFFI_UPCALLSINDEX_H\n");
6567
}

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

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797
import com.oracle.truffle.r.runtime.data.RTypedValue;
9898
import com.oracle.truffle.r.runtime.data.RUnboundValue;
9999
import com.oracle.truffle.r.runtime.data.RVector;
100+
import com.oracle.truffle.r.runtime.data.RWeakRef;
100101
import com.oracle.truffle.r.runtime.data.model.RAbstractAtomicVector;
101102
import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
102103
import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
@@ -375,6 +376,9 @@ public Object Rf_installChar(Object name) {
375376
@Override
376377
@TruffleBoundary
377378
public Object Rf_lengthgets(Object x, int newSize) {
379+
if (x == RNull.instance) {
380+
return RNull.instance;
381+
}
378382
RAbstractVector vec = (RAbstractVector) RRuntime.asAbstractVector(x);
379383
return vec.resize(newSize);
380384
}
@@ -1545,6 +1549,32 @@ public Object R_MethodsNamespace() {
15451549
return REnvironment.getRegisteredNamespace("methods");
15461550
}
15471551

1552+
// basic support for weak reference API - they are not actually weak and don't call finalizers
1553+
1554+
@Override
1555+
@TruffleBoundary
1556+
public Object R_MakeWeakRef(Object key, Object val, Object fin, long onexit) {
1557+
return new RWeakRef(key, val, fin, onexit != 0);
1558+
}
1559+
1560+
@Override
1561+
@TruffleBoundary
1562+
public Object R_MakeWeakRefC(Object key, Object val, long fin, long onexit) {
1563+
return new RWeakRef(key, val, fin, onexit != 0);
1564+
}
1565+
1566+
@Override
1567+
@TruffleBoundary
1568+
public Object R_WeakRefKey(Object w) {
1569+
return guaranteeInstanceOf(w, RWeakRef.class).getKey();
1570+
}
1571+
1572+
@Override
1573+
@TruffleBoundary
1574+
public Object R_WeakRefValue(Object w) {
1575+
return guaranteeInstanceOf(w, RWeakRef.class).getValue();
1576+
}
1577+
15481578
@Override
15491579
@TruffleBoundary
15501580
public void R_PreserveObject(Object obj) {
@@ -1587,11 +1617,20 @@ public Object Rf_protect(Object x) {
15871617
public void Rf_unprotect(int x) {
15881618
RFFIContext context = getContext();
15891619
ArrayList<RObject> stack = context.rffiContextState.protectStack;
1590-
for (int i = 0; i < x; i++) {
1591-
context.registerReferenceUsedInNative(stack.remove(stack.size() - 1));
1620+
try {
1621+
for (int i = 0; i < x; i++) {
1622+
context.registerReferenceUsedInNative(stack.remove(stack.size() - 1));
1623+
}
1624+
} catch (ArrayIndexOutOfBoundsException e) {
1625+
debugWarning("mismatched protect/unprotect (unprotect with empty protect stack)");
15921626
}
15931627
}
15941628

1629+
private static boolean debugWarning(String message) {
1630+
RError.warning(RError.SHOW_CALLER, RError.Message.GENERIC, message);
1631+
return true;
1632+
}
1633+
15951634
@Override
15961635
@TruffleBoundary
15971636
public int R_ProtectWithIndex(Object x) {

com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/FFI_RForeignAccessFactoryImpl.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2019, 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,6 +26,8 @@
2626
import com.oracle.truffle.r.runtime.data.CharSXPWrapper;
2727
import com.oracle.truffle.r.runtime.data.CharSXPWrapperMRForeign;
2828
import com.oracle.truffle.r.runtime.data.RTruffleObject;
29+
import com.oracle.truffle.r.runtime.data.RWeakRef;
30+
import com.oracle.truffle.r.runtime.data.RWeakRefMRForeign;
2931
import com.oracle.truffle.r.runtime.ffi.DLL;
3032

3133
public class FFI_RForeignAccessFactoryImpl {
@@ -36,6 +38,8 @@ public static ForeignAccess getForeignAccess(RTruffleObject obj) {
3638
return DLLDotSymbolMRForeign.ACCESS;
3739
} else if (obj instanceof CharSXPWrapper) {
3840
return CharSXPWrapperMRForeign.ACCESS;
41+
} else if (obj instanceof RWeakRef) {
42+
return RWeakRefMRForeign.ACCESS;
3943
} else {
4044
return null;
4145
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,9 @@ public static RfSetAttribNode create() {
106106

107107
@Specialization(guards = "!isNull(value)")
108108
protected Object setValue(RAttributable target, Object name, Object value,
109+
@Cached("create()") InternStringNode intern,
109110
@Cached("create()") SetAttributeNode setAttribNode) {
110-
setAttribNode.execute(target, (String) getCastNameNode().doCast(name), value);
111+
setAttribNode.execute(target, intern.execute((String) getCastNameNode().doCast(name)), value);
111112
return RNull.instance;
112113
}
113114

@@ -118,8 +119,9 @@ protected Object setValue(@SuppressWarnings("unused") RNull target, @SuppressWar
118119

119120
@Specialization
120121
protected Object unsetValue(RAttributable target, Object name, @SuppressWarnings("unused") RNull nullVal,
122+
@Cached("create()") InternStringNode intern,
121123
@Cached("create()") RemoveAttributeNode removeAttributeNode) {
122-
removeAttributeNode.execute(target, (String) getCastNameNode().doCast(name));
124+
removeAttributeNode.execute(target, intern.execute((String) getCastNameNode().doCast(name)));
123125
return RNull.instance;
124126
}
125127

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2019, 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
@@ -27,6 +27,14 @@
2727
public interface MemoryUpCallsRFFI {
2828
// Checkstyle: stop method name check
2929

30+
Object R_MakeWeakRef(Object key, Object val, Object fin, long onexit);
31+
32+
Object R_MakeWeakRefC(Object key, Object val, long fin, long onexit);
33+
34+
Object R_WeakRefKey(Object w);
35+
36+
Object R_WeakRefValue(Object w);
37+
3038
void R_PreserveObject(Object obj);
3139

3240
void R_ReleaseObject(Object obj);

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
@RFFIUpCallRoot
3333
public interface UpCallsRFFI extends StdUpCallsRFFI, IDEUpCallsRFFI, VariableUpCallsRFFI, DLLUpCallsRFFI, MemoryUpCallsRFFI, FastRUpCalls {
3434

35+
// methods in here are not considered by FFIUpCallsIndexCodeGen
36+
3537
interface HandleUpCallExceptionNode extends NodeInterface {
3638
void execute(Throwable ex);
3739
}

com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/CompleteCases.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* Copyright (c) 1995, 1996 Robert Gentleman and Ross Ihaka
33
* Copyright (c) 1997-2013, The R Core Team
4-
* Copyright (c) 2015, 2018, Oracle and/or its affiliates
4+
* Copyright (c) 2015, 2019, Oracle and/or its affiliates
55
*
66
* This program is free software; you can redistribute it and/or modify
77
* it under the terms of the GNU General Public License as published by
@@ -166,6 +166,8 @@ private void iterateAbstractVectorContents(int len, byte[] result, Object obj) {
166166
result[e % len] = RRuntime.LOGICAL_FALSE;
167167
}
168168
}
169+
} else if (entry == RNull.instance) {
170+
// ignore NULL values
169171
} else {
170172
throw invalidType(entry);
171173
}

com.oracle.truffle.r.native/fficall/src/common/Rinternals_common.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ void *DATAPTR(SEXP x) {
118118
} else if (type == CPLXSXP) {
119119
return COMPLEX(x);
120120
} else if (type == CHARSXP) {
121-
return R_CHAR(x);
121+
return (void*) R_CHAR(x);
122122
} else {
123123
return FASTR_DATAPTR(x);
124124
}

0 commit comments

Comments
 (0)