Skip to content

Commit e4760e8

Browse files
committed
[GR-14327] [GR-14527] [GR-14784] Misc Truffle ecosystem related improvements.
PullRequest: fastr/1982
2 parents 4e586a2 + 708dee7 commit e4760e8

File tree

14 files changed

+244
-41
lines changed

14 files changed

+244
-41
lines changed

CHANGELOG.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,21 @@
44
* new Truffle interop converts `double` values to `int` values if they fit in the integer range
55
* see the changes in the [spec tests](https://github.com/oracle/fastr/commit/e08e2b19571479dddb6167d9a1d492a14cb4c7b2#diff-c842fa11097793b19bd410589c36af99)
66

7+
Added missing R builtins and C APIa
8+
9+
* simple support for the weak reference API functions (`R_MakeWeakRef`, `R_MakeWeakRefC`, `R_WeakRefKey`, `R_WeakRefValue`)
10+
* `Rf_i1mach`
11+
* `gzcon` builtin for `url` connections, e.g., `load(url('protocol://path'))` should work now
12+
* `Sys.localeconv` supports: `decimal_point`, `thousands_sep`, `grouping`, `int_curr_symbol`, `currency_symbol`, `mon_decimal_point`,
13+
`mon_thousands_sep`, `mon_grouping`, `int_frac_digits`, `p_cs_precedes`, other fields are fixed to some meaningful but not culture
14+
sensitive value for given field
15+
716
Bug fixes:
817

918
* `rep.int` with value argument of length 0 just returns the value argument
1019
* `tcrossprod` called from `apply` did not give correct result #60
1120
* `Rf_lengthgets` can accept `NULL` argument
12-
13-
Added missing R builtins and C APIa
14-
15-
* simple support for the weak reference API functions (`R_MakeWeakRef`, `R_MakeWeakRefC`, `R_WeakRefKey`, `R_WeakRefValue`)
16-
* `Rf_i1mach`
21+
* FastR does not allow Java interop when not started with `--jvm`
1722

1823
# 1.0 RC 14
1924

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

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
import com.oracle.truffle.r.runtime.context.RContext;
6262
import com.oracle.truffle.r.runtime.context.TruffleRLanguage;
6363
import com.oracle.truffle.r.runtime.data.RFunction;
64+
import com.oracle.truffle.r.runtime.data.RInteropScalar.RInteropNA;
6465
import com.oracle.truffle.r.runtime.data.RPromise;
6566
import com.oracle.truffle.r.runtime.data.RTypedValue;
6667
import com.oracle.truffle.r.runtime.env.REnvironment;
@@ -140,6 +141,21 @@ protected void disposeContext(RContext context) {
140141

141142
@Override
142143
protected String toString(RContext context, Object value) {
144+
// primitive values are never produced by FastR so we don't print them as R vectors
145+
if (value instanceof Boolean) {
146+
// boolean constants are capitalized like in R
147+
return (boolean) value ? "TRUE" : "FALSE";
148+
}
149+
if (value instanceof Number || value instanceof String || value instanceof Character) {
150+
return value.toString();
151+
}
152+
153+
// special class designated to exchange NA values with the outside world
154+
// this value is a scalar, the only way to get it is via getArrayMember on an R vector
155+
if (value instanceof RInteropNA) {
156+
return "NA";
157+
}
158+
143159
// the debugger also passes result of TruffleRLanguage.findMetaObject() to this method
144160
Object unwrapped = value;
145161
// print promises by other means than the "print" function to avoid evaluating them
@@ -155,8 +171,11 @@ protected String toString(RContext context, Object value) {
155171
if (RMissingHelper.isMissing(unwrapped)) {
156172
return "missing";
157173
}
158-
Object asVector = RRuntime.asAbstractVector(unwrapped);
159-
if (!(asVector instanceof TruffleObject)) {
174+
175+
// the value unwrapped from an RPromise can be primitive Java type, but now we know that we
176+
// are dealing with primitive that is supposed to be treated as R vector
177+
unwrapped = RRuntime.asAbstractVector(unwrapped);
178+
if (!(unwrapped instanceof TruffleObject)) {
160179
throw RError.error(RError.NO_CALLER, Message.GENERIC, String.format("Printing value of type '%s' is not supported by the R language.", unwrapped.getClass().getSimpleName()));
161180
}
162181
Object printObj = REnvironment.baseEnv(context).get("print");
@@ -171,7 +190,7 @@ protected String toString(RContext context, Object value) {
171190
try {
172191
StringBuilder buffer = new StringBuilder();
173192
stateStdConnections.setBuffer(buffer);
174-
RContext.getEngine().evalFunction((RFunction) printObj, callingFrame, RCaller.topLevel, false, ArgumentsSignature.empty(1), asVector);
193+
RContext.getEngine().evalFunction((RFunction) printObj, callingFrame, RCaller.topLevel, false, ArgumentsSignature.empty(1), unwrapped);
175194
// remove the last "\n", which is useful for REPL, but not here
176195
if (buffer.length() > 0 && buffer.charAt(buffer.length() - 1) == '\n') {
177196
buffer.setLength(buffer.length() - 1);

com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/RMain.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,8 @@ protected void launch(Builder contextBuilderIn) {
180180
}
181181
this.consoleHandler = ConsoleHandler.createConsoleHandler(options, null, inStream, outStream);
182182
Builder contextBuilder = contextBuilderIn;
183-
if (!ignoreJvmArguments) {
184-
contextBuilder = contextBuilder.allowHostAccess(useJVM);
183+
if (!ignoreJvmArguments && !useJVM) {
184+
contextBuilder.allowHostClassLookup(null);
185185
}
186186

187187
Context context;

com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInterop.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,12 @@ protected Object eval(@SuppressWarnings("unused") RMissing code, @SuppressWarnin
258258
}
259259
}
260260

261+
private static void checkPolyglotAccess(Env env) {
262+
if (!env.isPolyglotAccessAllowed()) {
263+
throw RError.error(RError.SHOW_CALLER, RError.Message.POLYGLOT_BINDING_NOT_AVAILABLE);
264+
}
265+
}
266+
261267
@RBuiltin(name = "export", visibility = OFF, kind = PRIMITIVE, parameterNames = {"name", "value"}, behavior = COMPLEX)
262268
public abstract static class Export extends RBuiltinNode.Arg2 {
263269

@@ -273,7 +279,9 @@ protected Object exportSymbol(String name, TruffleObject value) {
273279
if (name == null) {
274280
throw error(RError.Message.INVALID_ARGUMENT, "name");
275281
}
276-
RContext.getInstance().getEnv().exportSymbol(name, value);
282+
Env env = RContext.getInstance().getEnv();
283+
checkPolyglotAccess(env);
284+
env.exportSymbol(name, value);
277285
return RNull.instance;
278286
}
279287

@@ -301,7 +309,9 @@ public abstract static class Import extends RBuiltinNode.Arg1 {
301309
@Specialization
302310
@TruffleBoundary
303311
protected Object importSymbol(String name) {
304-
Object object = RContext.getInstance().getEnv().importSymbol(name);
312+
Env env = RContext.getInstance().getEnv();
313+
checkPolyglotAccess(env);
314+
Object object = env.importSymbol(name);
305315
if (object == null) {
306316
throw error(RError.Message.NO_IMPORT_OBJECT, name);
307317
}

com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1032,7 +1032,8 @@ public enum Message {
10321032
"SET_ATTRIB: tag in the attributes pairlist must be a symbol. %s given. It is possible that the code intends to set the TAG after the call to SET_ATTRIB, but this is not supported in FastR."),
10331033
WRONG_ARGS_COMBINATION("Wrong arguments combination, please refer to ?%s for more details."),
10341034
COULD_NOT_FIND_LANGUAGE("Could not find language corresponding to extension '%s', you can specify the language id explicitly, please refer to ?%s for more details."),
1035-
LANGUAGE_NOT_AVAILABLE("Language with id '%s' is not available. Did you start R with --polyglot?"),
1035+
LANGUAGE_NOT_AVAILABLE("Language with id '%s' is not available. Did you start R with --polyglot or use allowPolyglotAccess when building the context?"),
1036+
POLYGLOT_BINDING_NOT_AVAILABLE("Polyglot bindings are not accessible for this language. Use --polyglot or allowPolyglotAccess when building the context."),
10361037
NO_LANGUAGE_PROVIDED("No language id provided, please refer to ?%s for more details."),
10371038
NO_CODE_OR_PATH_PROVIDED("No code or path provided, please refer to ?%s for more details."),
10381039
LENGTH_OF_NULL_UNCHANGED("length of NULL cannot be changed"),

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ public class PackagePatching {
6464
new Patch("reinterpret_cast<.*>\\((.*)\\)->gp &= (\\w+|\\(.*\\))", "SETLEVELS($1, LEVELS($1) & ($2))"),
6565
new Patch("reinterpret_cast<.*>\\((.*)\\)->gp \\|= (\\w+|\\(.*\\))", "SETLEVELS($1, LEVELS($1) | ($2))"),
6666
new Patch("reinterpret_cast<.*>\\((.*)\\)->gp \\^= (\\w+|\\(.*\\))", "SETLEVELS($1, LEVELS($1) ^ ($2))"),
67+
// FastR does not support these global variables:
68+
new Patch("R_Interactive\\s*=\\s*[01]", ""),
69+
new Patch("R_isForkedChild\\s*=\\s*[01]", ""),
70+
new Patch("Rf_KillAllDevices\\s*\\(\\s*\\)", ""),
6771
};
6872

6973
@TruffleBoundary

com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29323,6 +29323,10 @@ NULL
2932329323
#environment(print)
2932429324
<environment: namespace:base>
2932529325

29326+
##com.oracle.truffle.r.test.builtins.TestBuiltin_environment.testEnvironment#
29327+
#{ env <- list2env(list(customenvvar = 42)); fst <- function(fstvar) do.call(environment, list(), envir = env); a <- fst(0); ls(a) }
29328+
[1] "customenvvar"
29329+
2932629330
##com.oracle.truffle.r.test.builtins.TestBuiltin_environment.testEnvironment#
2932729331
#{ f <- y~z; class(f) <- c('myclass', class(f)); environment(f) }
2932829332
<environment: R_GlobalEnv>
@@ -54102,47 +54106,47 @@ expression(for (i in 1:10) {
5410254106
x[i] <- i
5410354107
})
5410454108

54105-
##com.oracle.truffle.r.test.builtins.TestBuiltin_parse.testSource#Output.IgnoreWarningMessage#
54109+
##com.oracle.truffle.r.test.builtins.TestBuiltin_parse.testSource#
5410654110
#{ source("test/r/simple/data/tree2/setx.r") ; x }
5410754111
Error in file(filename, "r", encoding = encoding) :
5410854112
cannot open the connection
5410954113
In addition: Warning message:
5411054114
In file(filename, "r", encoding = encoding) :
5411154115
cannot open file 'test/r/simple/data/tree2/setx.r': No such file or directory
5411254116

54113-
##com.oracle.truffle.r.test.builtins.TestBuiltin_parse.testSource#Output.IgnoreWarningMessage#
54117+
##com.oracle.truffle.r.test.builtins.TestBuiltin_parse.testSource#
5411454118
#{ source("test/r/simple/data/tree2/setx.r", local=TRUE) ; x }
5411554119
Error in file(filename, "r", encoding = encoding) :
5411654120
cannot open the connection
5411754121
In addition: Warning message:
5411854122
In file(filename, "r", encoding = encoding) :
5411954123
cannot open file 'test/r/simple/data/tree2/setx.r': No such file or directory
5412054124

54121-
##com.oracle.truffle.r.test.builtins.TestBuiltin_parse.testSource#Output.IgnoreWarningMessage#
54125+
##com.oracle.truffle.r.test.builtins.TestBuiltin_parse.testSource#
5412254126
#{ x <- 1; f <- function() { source("test/r/simple/data/tree2/incx.r", local=FALSE) ; x } ; c(f(), x) }
5412354127
Error in file(filename, "r", encoding = encoding) :
5412454128
cannot open the connection
5412554129
In addition: Warning message:
5412654130
In file(filename, "r", encoding = encoding) :
5412754131
cannot open file 'test/r/simple/data/tree2/incx.r': No such file or directory
5412854132

54129-
##com.oracle.truffle.r.test.builtins.TestBuiltin_parse.testSource#Output.IgnoreWarningMessage#
54133+
##com.oracle.truffle.r.test.builtins.TestBuiltin_parse.testSource#
5413054134
#{ x <- 1; f <- function() { source("test/r/simple/data/tree2/incx.r", local=TRUE) ; x } ; c(f(), x) }
5413154135
Error in file(filename, "r", encoding = encoding) :
5413254136
cannot open the connection
5413354137
In addition: Warning message:
5413454138
In file(filename, "r", encoding = encoding) :
5413554139
cannot open file 'test/r/simple/data/tree2/incx.r': No such file or directory
5413654140

54137-
##com.oracle.truffle.r.test.builtins.TestBuiltin_parse.testSource#Output.IgnoreWarningMessage#
54141+
##com.oracle.truffle.r.test.builtins.TestBuiltin_parse.testSource#
5413854142
#{ x <- 1; f <- function() { source("test/r/simple/data/tree2/setx.r", local=FALSE) ; x } ; c(f(), x) }
5413954143
Error in file(filename, "r", encoding = encoding) :
5414054144
cannot open the connection
5414154145
In addition: Warning message:
5414254146
In file(filename, "r", encoding = encoding) :
5414354147
cannot open file 'test/r/simple/data/tree2/setx.r': No such file or directory
5414454148

54145-
##com.oracle.truffle.r.test.builtins.TestBuiltin_parse.testSource#Output.IgnoreWarningMessage#
54149+
##com.oracle.truffle.r.test.builtins.TestBuiltin_parse.testSource#
5414654150
#{ x <- 1; f <- function() { source("test/r/simple/data/tree2/setx.r", local=TRUE) ; x } ; c(f(), x) }
5414754151
Error in file(filename, "r", encoding = encoding) :
5414854152
cannot open the connection
@@ -150339,24 +150343,24 @@ Error: unexpected ';' in "if (!any(R.version$engine == "FastR")) { TRUE } else {
150339150343
[1] "123"
150340150344

150341150345
##com.oracle.truffle.r.test.library.fastr.TestInterop.testInteropEval#
150342-
#if (!any(R.version$engine == "FastR")) { cat('Error in eval.polyglot("foo", "bar") :\n Language with id \'foo\' is not available. Did you start R with --polyglot?\n') } else { eval.polyglot('foo', 'bar') }
150346+
#if (!any(R.version$engine == "FastR")) { cat('Error in eval.polyglot("foo", "bar") :\n Language with id \'foo\' is not available. Did you start R with --polyglot or use allowPolyglotAccess when building the context?\n') } else { eval.polyglot('foo', 'bar') }
150343150347
Error in eval.polyglot("foo", "bar") :
150344-
Language with id 'foo' is not available. Did you start R with --polyglot?
150348+
Language with id 'foo' is not available. Did you start R with --polyglot or use allowPolyglotAccess when building the context?
150345150349

150346150350
##com.oracle.truffle.r.test.library.fastr.TestInterop.testInteropEval#
150347-
#if (!any(R.version$engine == "FastR")) { cat('Error in eval.polyglot("foo", , "bar") :\n Language with id \'foo\' is not available. Did you start R with --polyglot?\n') } else { eval.polyglot('foo',, 'bar') }
150351+
#if (!any(R.version$engine == "FastR")) { cat('Error in eval.polyglot("foo", , "bar") :\n Language with id \'foo\' is not available. Did you start R with --polyglot or use allowPolyglotAccess when building the context?\n') } else { eval.polyglot('foo',, 'bar') }
150348150352
Error in eval.polyglot("foo", , "bar") :
150349-
Language with id 'foo' is not available. Did you start R with --polyglot?
150353+
Language with id 'foo' is not available. Did you start R with --polyglot or use allowPolyglotAccess when building the context?
150350150354

150351150355
##com.oracle.truffle.r.test.library.fastr.TestInterop.testInteropEval#
150352-
#if (!any(R.version$engine == "FastR")) { cat('Error in eval.polyglot("nfi", "foo.bar") :\n Language with id \'nfi\' is not available. Did you start R with --polyglot?\n') } else { eval.polyglot('nfi', 'foo.bar') }
150356+
#if (!any(R.version$engine == "FastR")) { cat('Error in eval.polyglot("nfi", "foo.bar") :\n Language with id \'nfi\' is not available. Did you start R with --polyglot or use allowPolyglotAccess when building the context?\n') } else { eval.polyglot('nfi', 'foo.bar') }
150353150357
Error in eval.polyglot("nfi", "foo.bar") :
150354-
Language with id 'nfi' is not available. Did you start R with --polyglot?
150358+
Language with id 'nfi' is not available. Did you start R with --polyglot or use allowPolyglotAccess when building the context?
150355150359

150356150360
##com.oracle.truffle.r.test.library.fastr.TestInterop.testInteropEval#
150357-
#if (!any(R.version$engine == "FastR")) { cat('Error in eval.polyglot("nfi", , "foo.bar") :\n Language with id \'nfi\' is not available. Did you start R with --polyglot?\n') } else { eval.polyglot('nfi',,'foo.bar') }
150361+
#if (!any(R.version$engine == "FastR")) { cat('Error in eval.polyglot("nfi", , "foo.bar") :\n Language with id \'nfi\' is not available. Did you start R with --polyglot or use allowPolyglotAccess when building the context?\n') } else { eval.polyglot('nfi',,'foo.bar') }
150358150362
Error in eval.polyglot("nfi", , "foo.bar") :
150359-
Language with id 'nfi' is not available. Did you start R with --polyglot?
150363+
Language with id 'nfi' is not available. Did you start R with --polyglot or use allowPolyglotAccess when building the context?
150360150364

150361150365
##com.oracle.truffle.r.test.library.fastr.TestInterop.testInteropEval#
150362150366
#if (!any(R.version$engine == "FastR")) { cat('Error in eval.polyglot(, "bar") :\n No language id provided, please refer to ?eval.polyglot for more details.\n') } else { eval.polyglot(, 'bar') }
@@ -150378,9 +150382,9 @@ Error in eval.polyglot("js", "console.log(42)", "file.js") :
150378150382
Wrong arguments combination, please refer to ?eval.polyglot for more details.
150379150383

150380150384
##com.oracle.truffle.r.test.library.fastr.TestInterop.testInteropEvalFile#
150381-
#if (!any(R.version$engine == "FastR")) { cat('Error in eval.polyglot("nonExistentLanguage", "code") :<<<NEWLINE>>> Language with id \'nonExistentLanguage\' is not available. Did you start R with --polyglot?\n') } else { eval.polyglot('nonExistentLanguage', 'code') }
150385+
#if (!any(R.version$engine == "FastR")) { cat('Error in eval.polyglot("nonExistentLanguage", "code") :<<<NEWLINE>>> Language with id \'nonExistentLanguage\' is not available. Did you start R with --polyglot or use allowPolyglotAccess when building the context?\n') } else { eval.polyglot('nonExistentLanguage', 'code') }
150382150386
Error in eval.polyglot("nonExistentLanguage", "code") :
150383-
Language with id 'nonExistentLanguage' is not available. Did you start R with --polyglot?
150387+
Language with id 'nonExistentLanguage' is not available. Did you start R with --polyglot or use allowPolyglotAccess when building the context?
150384150388

150385150389
##com.oracle.truffle.r.test.library.fastr.TestInterop.testInteropEvalFile#
150386150390
#if (!any(R.version$engine == "FastR")) { cat('Error in eval.polyglot("someLanguage") :<<<NEWLINE>>> No code or path provided, please refer to ?eval.polyglot for more details.\n') } else { eval.polyglot('someLanguage') }

0 commit comments

Comments
 (0)