From 51a8d559f7df8383e312384d9b1a42d33b39f78b Mon Sep 17 00:00:00 2001 From: stepan <stepan.sindelar@oracle.com> Date: Mon, 30 Jan 2017 15:13:16 +0100 Subject: [PATCH] Initial grid package support --- .gitignore | 2 + .../library/grid/Makefile | 39 +++++++++++++--- .../library/grid/src/sed_grid | 10 +++++ .../library/grid/src/sed_state | 18 ++++++++ .../foreign/CallAndExternalFunctions.java | 14 ++++-- .../truffle/r/test/ExpectedTestOutput.test | 16 +++++++ .../r/test/library/grid/TestGridPackage.java | 44 +++++++++++++++++++ mx.fastr/mx_fastr.py | 2 +- 8 files changed, 135 insertions(+), 10 deletions(-) create mode 100644 com.oracle.truffle.r.native/library/grid/src/sed_grid create mode 100644 com.oracle.truffle.r.native/library/grid/src/sed_state create mode 100644 com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/grid/TestGridPackage.java diff --git a/.gitignore b/.gitignore index dd8ad6fc9f..9c8ffbab24 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,8 @@ /com.oracle.truffle.r.native/library/*/lib/* /com.oracle.truffle.r.native/library/stats/src/fft.c /com.oracle.truffle.r.native/library/tools/src/gramRd.c +/com.oracle.truffle.r.native/library/grid/src/grid.c +/com.oracle.truffle.r.native/library/grid/src/state.c /com.oracle.truffle.r.native/platform.mk /com.oracle.truffle.r.native/gnur/Makeconf.done /com.oracle.truffle.r.native/gnur/platform.mk.temp* diff --git a/com.oracle.truffle.r.native/library/grid/Makefile b/com.oracle.truffle.r.native/library/grid/Makefile index 58f1789a96..4ef8f605d9 100644 --- a/com.oracle.truffle.r.native/library/grid/Makefile +++ b/com.oracle.truffle.r.native/library/grid/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -21,14 +21,43 @@ # questions. # +.PHONY: cleanpkg + OBJ = lib -GNUR_C_FILES := $(notdir $(wildcard $(GNUR_HOME)/src/library/grid/src/*.c)) +GNUR_C_FILES := gpar.c just.c layout.c matrix.c register.c unit.c util.c viewport.c + +GNUR_GRID = $(addprefix $(GNUR_HOME)/src/library/grid/src/, grid.c) +GRID_OBJECT = $(addprefix $(OBJ)/, grid.o) + +GNUR_GRID_STATE = $(addprefix $(GNUR_HOME)/src/library/grid/src/, state.c) +GRID_STATE_OBJECT = $(addprefix $(OBJ)/, state.o) -GNUR_C_OBJECTS := $(addprefix $(OBJ)/, $(GNUR_C_FILES:.c=.o)) -#$(info GNUR_C_OBJECTS=$(GNUR_C_OBJECTS)) +GNUR_C_OBJECTS := $(addprefix $(OBJ)/, $(GNUR_C_FILES:.c=.o)) $(GRID_OBJECT) $(GRID_STATE_OBJECT) +LIB_PKG_PRE = $(GRID_OBJECT) $(GRID_STATE_OBJECT) +CLEAN_PKG := cleanpkg + +# This is necessary so that #include "grid.h" works +PKG_INCLUDES = -I $(GNUR_SRC) include ../lib.mk +# Why is this necessary? Because if grid.c and state.c have been created by editing, +# lib.mk will include them in C_OBJECTS but they're already in GNUR_C_OBJECTS (uncreated case) +C_OBJECTS := $(filter-out $(GRID_OBJECT) $(GRID_STATE_OBJECT), $(C_OBJECTS)) + +$(C_OBJECTS): | $(OBJ) + +$(SRC)/grid.c: $(GNUR_GRID) src/sed_grid + sed -f src/sed_grid $(GNUR_GRID) > src/grid.c + +$(SRC)/state.c: $(GNUR_GRID_STATE) src/sed_state + sed -f src/sed_state $(GNUR_GRID_STATE) > src/state.c + +# obj files from c.o.t.r.n/library/grid/src are handled in lib.mk +# obj files from gnur to c.o.t.r.n/library/grid/lib are handled here $(OBJ)/%.o: $(GNUR_SRC)/%.c - $(CC) $(CFLAGS) $(INCLUDES) $(SUPPRESS_WARNINGS) -c $< -o $@ + $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ + +cleanpkg: + rm -f $(SRC)/grid.c $(SRC)/state.c diff --git a/com.oracle.truffle.r.native/library/grid/src/sed_grid b/com.oracle.truffle.r.native/library/grid/src/sed_grid new file mode 100644 index 0000000000..507382a2dc --- /dev/null +++ b/com.oracle.truffle.r.native/library/grid/src/sed_grid @@ -0,0 +1,10 @@ +# L_initGrid gets environment from its caller, which is .External, and saves it +# into a static variable R_gridEvalEnv without calling R_PreserveObject. In the +# Gnu R world, the environment actually cannot be garbage collected, because it +# is grid's environment and there are references to it. +# +# Moreover, grid also uses this environment to "preserve" other objects just by +# adding them to that environment. See ed_state where we fix code doing this to +# also call R_PreserveObject and R_ReleaseObject. +# +s/R_gridEvalEnv = \([[:alnum:]]*\);/R_gridEvalEnv = R_PreserveObject(\1);/g diff --git a/com.oracle.truffle.r.native/library/grid/src/sed_state b/com.oracle.truffle.r.native/library/grid/src/sed_state new file mode 100644 index 0000000000..4cd242c4b4 --- /dev/null +++ b/com.oracle.truffle.r.native/library/grid/src/sed_state @@ -0,0 +1,18 @@ +# see ed_grid for description of what is going on here. +# +# Note: the state cannot be 'preserved' in globaliseState(SEXP) +# function, which would seem as appropriate place, because the +# state is stored into a global variable before globaliseState +# is invoked. +# +# prepend R_PreserveObject call to any sd->systemSpecific assignment +# in form of sd->systemSpecific = (void*) variablename; +s/sd->systemSpecific[[:space:]]*=[[:space:]]*(void\*)[[:space:]]*\([[:alnum:]_]*\);/\1 = R_PreserveObject(\1); sd->systemSpecific = (void*)\1;/g +# +# rename deglobaliseState to deglobaliseStateOriginal and prepend a +# new definition of deglobaliseState that calls R_ReleaseObject and +# the original function (note we need deglobaliseStateOriginal +# forward declaration) +s/static void deglobaliseState(SEXP state)/static void deglobaliseStateOriginal(SEXP state);\ +static void deglobaliseState(SEXP state) { deglobaliseStateOriginal(state); R_ReleaseObject(state); }\ +static void deglobaliseStateOriginal(SEXP state)/g diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java index 1288d98ba2..038de21300 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java @@ -621,6 +621,16 @@ public class CallAndExternalFunctions { case "sockwrite": return new UnimplementedExternal(name); + // parallel + case "mc_is_child": + return MCIsChildNodeGen.create(); + default: + return FastROptions.UseInternalGraphics.getBooleanValue() ? lookupGraphicsBuiltin(name) : null; + } + } + + private RExternalBuiltinNode lookupGraphicsBuiltin(String name) { + switch (name) { // grDevices case "cairoProps": return CairoPropsNodeGen.create(); @@ -632,10 +642,6 @@ public class CallAndExternalFunctions { return InitGridNodeGen.create(); case "L_validUnits": return ValidUnitsNodeGen.create(); - - // parallel - case "mc_is_child": - return MCIsChildNodeGen.create(); default: return null; } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test index 4d335cc1b9..6f6cf33436 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test @@ -125207,6 +125207,22 @@ attr(,"is.truffle.object") #if (length(grep("FastR", R.Version()$version.string)) != 1) { TRUE } else { { x<-rep(1, 100); xi1<-.fastr.identity(x); f<-function(x) { y<-x; y }; f(x); x[1]<-7; xi2<-.fastr.identity(x); xi1 == xi2 } } [1] TRUE +##com.oracle.truffle.r.test.library.grid.TestGridPackage.testUnits# +#{ library(grid); 3 * (unit(1, 'mm')); } +[1] 3*1mm + +##com.oracle.truffle.r.test.library.grid.TestGridPackage.testUnits# +#{ library(grid); grid:::unit.list(3 * unit(1, 'mm')); } +[1] 3*1mm + +##com.oracle.truffle.r.test.library.grid.TestGridPackage.testUnits# +#{ library(grid); unit.c(unit(1,'mm'), 42*unit(1,'mm')); } +[1] 1mm 42*1mm + +##com.oracle.truffle.r.test.library.grid.TestGridPackage.testUnits# +#{ library(grid); unit.c(unit(1,'mm'), unit(1,'mm')) } +[1] 1mm 1mm + ##com.oracle.truffle.r.test.library.stats.TestDistributions.testDensityFunctions#Output.MayIgnoreWarningContext# #dbeta(0, -1, 0.5) [1] NaN diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/grid/TestGridPackage.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/grid/TestGridPackage.java new file mode 100644 index 0000000000..f0e5c6639a --- /dev/null +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/grid/TestGridPackage.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.test.library.grid; + +import org.junit.Test; + +import com.oracle.truffle.r.test.TestBase; + +/** + * Tests non-graphical functions in grid package. + */ +public class TestGridPackage extends TestBase { + @Test + public void testUnits() { + run("unit.c(unit(1,'mm'), unit(1,'mm'))"); + run("3 * (unit(1, 'mm'));"); + run("grid:::unit.list(3 * unit(1, 'mm'));"); + run("unit.c(unit(1,'mm'), 42*unit(1,'mm'));"); + } + + private void run(String testCode) { + assertEval(String.format("{ library(grid); %s }", testCode)); + } +} diff --git a/mx.fastr/mx_fastr.py b/mx.fastr/mx_fastr.py index 70f6f5e127..e215042965 100644 --- a/mx.fastr/mx_fastr.py +++ b/mx.fastr/mx_fastr.py @@ -407,7 +407,7 @@ def _test_subpackage(name): return '.'.join((_test_package(), name)) def _simple_generated_unit_tests(): - return ','.join(map(_test_subpackage, ['library.base', 'library.stats', 'library.utils', 'library.fastr', 'builtins', 'functions', 'parser', 'S4', 'rng', 'runtime.data'])) + return ','.join(map(_test_subpackage, ['library.base', 'library.grid', 'library.stats', 'library.utils', 'library.fastr', 'builtins', 'functions', 'parser', 'S4', 'rng', 'runtime.data'])) def _simple_unit_tests(): return ','.join([_simple_generated_unit_tests(), _test_subpackage('tck')]) -- GitLab