diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java index 7589fcf8a876b1e29552a48df8e27e5fb4ddd724..b7cc4812af454213b9f08f7492e38b9332378514 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java @@ -25,7 +25,6 @@ package com.oracle.truffle.r.engine; import java.io.File; import java.util.Arrays; import java.util.List; -import java.util.Map; import java.util.stream.Collectors; import com.oracle.truffle.api.CallTarget; @@ -99,7 +98,6 @@ import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.RTypedValue; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.env.REnvironment; -import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor; import com.oracle.truffle.r.runtime.nodes.RCodeBuilder; import com.oracle.truffle.r.runtime.nodes.RNode; import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; @@ -250,7 +248,7 @@ final class REngine implements Engine, Engine.Timings { @Override public Object parseAndEval(Source source, MaterializedFrame frame, boolean printResult) throws ParseException { - List<RSyntaxNode> list = parseImpl(null, source); + List<RSyntaxNode> list = parseImpl(source); try { Object lastValue = RNull.instance; for (RSyntaxNode node : list) { @@ -279,31 +277,21 @@ final class REngine implements Engine, Engine.Timings { } } - private static List<RSyntaxNode> parseImpl(Map<String, Object> constants, Source source) throws ParseException { + private static List<RSyntaxNode> parseImpl(Source source) throws ParseException { RParserFactory.Parser<RSyntaxNode> parser = RParserFactory.getParser(); - return parser.script(source, new RASTBuilder(constants)); + return parser.script(source, new RASTBuilder()); } @Override - public RExpression parse(Map<String, Object> constants, Source source) throws ParseException { - List<RSyntaxNode> list = parseImpl(constants, source); + public RExpression parse(Source source) throws ParseException { + List<RSyntaxNode> list = parseImpl(source); Object[] data = list.stream().map(node -> RASTUtils.createLanguageElement(node)).toArray(); return RDataFactory.createExpression(data); } - @Override - public RFunction parseFunction(Map<String, Object> constants, String name, Source source, MaterializedFrame enclosingFrame) throws ParseException { - RParserFactory.Parser<RSyntaxNode> parser = RParserFactory.getParser(); - RootCallTarget callTarget = parser.rootFunction(source, name, new RASTBuilder(constants)); - FrameSlotChangeMonitor.initializeEnclosingFrame(callTarget.getRootNode().getFrameDescriptor(), enclosingFrame); - RFunction func = RDataFactory.createFunction(name, callTarget, null, enclosingFrame); - RInstrumentation.checkDebugRequested(func); - return func; - } - @Override public CallTarget parseToCallTarget(Source source) throws ParseException { - List<RSyntaxNode> statements = parseImpl(null, source); + List<RSyntaxNode> statements = parseImpl(source); return Truffle.getRuntime().createCallTarget(new PolyglotEngineRootNode(statements, createSourceSection(statements))); } diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java index 60b6a089028cf268afd4a74c3634019979dfcc84..7e846867c53f4cc0ea48208d559d36e5ffa49381 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java @@ -57,6 +57,7 @@ import com.oracle.truffle.r.nodes.control.ReplacementDispatchNode; import com.oracle.truffle.r.nodes.function.FunctionDefinitionNode; import com.oracle.truffle.r.nodes.function.FunctionExpressionNode; import com.oracle.truffle.r.nodes.function.RCallNode; +import com.oracle.truffle.r.nodes.instrumentation.RInstrumentation; import com.oracle.truffle.r.runtime.Arguments; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RArguments; @@ -712,4 +713,9 @@ class RRuntimeASTAccessImpl implements RRuntimeASTAccess { public String encodeComplex(RComplex x, int digits) { return ComplexVectorPrinter.encodeComplex(x, digits); } + + @Override + public void checkDebugRequest(RFunction func) { + RInstrumentation.checkDebugRequested(func); + } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/RBuiltinPackages.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/RBuiltinPackages.java index f5b340906fdc58d2532f2d91fe1a76a93178d8f8..0550a55c3bdd9628b69680a20f5fda5193ade6b6 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/RBuiltinPackages.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/RBuiltinPackages.java @@ -161,7 +161,7 @@ public final class RBuiltinPackages implements RBuiltinLookup { return function; } RootCallTarget callTarget = RBuiltinNode.createArgumentsCallTarget(builtinFactory); - function = RDataFactory.createFunction(builtinFactory.getName(), callTarget, builtinFactory, null); + function = RDataFactory.createFunction(builtinFactory.getName(), "base", callTarget, builtinFactory, null); cachedBuiltinFunctions.put(methodName, function); return function; } catch (Throwable t) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Args.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Args.java index 3e2232794d820121f706f64d602e1573d07f115a..c239b07b293abaec17216c177dff74b1cb2e986b 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Args.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Args.java @@ -38,7 +38,6 @@ import com.oracle.truffle.r.nodes.builtin.base.GetFunctionsFactory.GetNodeGen; import com.oracle.truffle.r.nodes.function.FormalArguments; import com.oracle.truffle.r.nodes.function.FunctionDefinitionNode; import com.oracle.truffle.r.nodes.function.SaveArgumentsNode; -import com.oracle.truffle.r.runtime.RDeparse; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RDataFactory; @@ -85,8 +84,7 @@ public abstract class Args extends RBuiltinNode { String newDesc = "args(" + rootNode.getDescription() + ")"; FunctionDefinitionNode newNode = FunctionDefinitionNode.create(RSyntaxNode.LAZY_DEPARSE, rootNode.getFrameDescriptor(), null, SaveArgumentsNode.NO_ARGS, ConstantNode.create(RSyntaxNode.LAZY_DEPARSE, RNull.instance), formals, newDesc, null); - RDeparse.ensureSourceSection(newNode); - return RDataFactory.createFunction(newDesc, Truffle.getRuntime().createCallTarget(newNode), null, REnvironment.globalEnv().getFrame()); + return RDataFactory.createFunction(newDesc, RFunction.NO_NAME, Truffle.getRuntime().createCallTarget(newNode), null, REnvironment.globalEnv().getFrame()); } @Specialization(guards = {"!isRFunction(fun)", "!isRAbstractStringVector(fun)"}) diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java index 20b61c1e9c4bc222f8520b032360d290b780279b..48e9c12212719efece862ee4d5346b8011cae3fe 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java @@ -76,7 +76,7 @@ public abstract class AsCharacter extends RBuiltinNode { } else if (elem instanceof RStringVector && ((RStringVector) elem).getLength() == 1) { data[i] = ((RStringVector) elem).getDataAt(0); } else { - data[i] = RDeparse.deparse(elem, RDeparse.MAX_Cutoff, true, 0, -1); + data[i] = RDeparse.deparse(elem); } if (RRuntime.isNA(data[i])) { complete = RDataFactory.INCOMPLETE_VECTOR; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java index 4c326d7e1158209e3a6a9129e329a6e0ec26d5f7..4c7ca302a832f3e56e0e2f08733f2e77564cdcd6 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java @@ -22,7 +22,7 @@ */ package com.oracle.truffle.r.nodes.builtin.base; -import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf; import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; @@ -41,7 +41,6 @@ import com.oracle.truffle.r.nodes.function.FormalArguments; import com.oracle.truffle.r.nodes.function.FunctionDefinitionNode; import com.oracle.truffle.r.nodes.function.SaveArgumentsNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; -import com.oracle.truffle.r.runtime.RDeparse; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; @@ -148,8 +147,7 @@ public abstract class AsFunction extends RBuiltinNode { FrameSlotChangeMonitor.initializeFunctionFrameDescriptor("<as.function.default>", descriptor); FrameSlotChangeMonitor.initializeEnclosingFrame(descriptor, envir.getFrame()); FunctionDefinitionNode rootNode = FunctionDefinitionNode.create(RSyntaxNode.LAZY_DEPARSE, descriptor, null, saveArguments, (RSyntaxNode) body, formals, "from AsFunction", null); - RDeparse.ensureSourceSection(rootNode); RootCallTarget callTarget = Truffle.getRuntime().createCallTarget(rootNode); - return RDataFactory.createFunction(RFunction.NO_NAME, callTarget, null, envir.getFrame()); + return RDataFactory.createFunction(RFunction.NO_NAME, RFunction.NO_NAME, callTarget, null, envir.getFrame()); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java index c41d24f58409f369f09262b4a3bbf0d4fecbf216..e5ae35b08c784065f46fd10c6b38abd451044f51 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java @@ -392,7 +392,7 @@ public class EnvFunctions { RRootNode root = (RRootNode) fun.getTarget().getRootNode(); RootCallTarget target = root.duplicateWithNewFrameDescriptor(); FrameSlotChangeMonitor.initializeEnclosingFrame(target.getRootNode().getFrameDescriptor(), enclosingFrame); - return RDataFactory.createFunction(fun.getName(), target, null, enclosingFrame); + return RDataFactory.createFunction(fun.getName(), fun.getPackageName(), target, null, enclosingFrame); } @Specialization diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java index 69c479a93f36952fce3275cc57265b45a24cb5cc..8ac93354d9a2fdb4f9223c82978ee91a8110bf19 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java @@ -136,7 +136,7 @@ public abstract class Parse extends RBuiltinNode { } try { Source source = srcFile != RNull.instance ? createSource(srcFile, coalescedLines) : createSource(conn, coalescedLines); - RExpression exprs = RContext.getEngine().parse(null, source); + RExpression exprs = RContext.getEngine().parse(source); if (n > 0 && n < exprs.getLength()) { Object[] subListData = new Object[n]; for (int i = 0; i < n; i++) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/FunctionPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/FunctionPrinter.java index 15be08089ae5981033eebd892c300a56eb68abe4..d8de3b9f0c34652365a9f3a7665984c8d9426eb6 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/FunctionPrinter.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/FunctionPrinter.java @@ -26,6 +26,7 @@ import java.io.IOException; import java.io.PrintWriter; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.r.nodes.RRootNode; import com.oracle.truffle.r.nodes.access.ConstantNode; import com.oracle.truffle.r.nodes.function.FormalArguments; @@ -36,6 +37,8 @@ import com.oracle.truffle.r.runtime.builtins.RBuiltinDescriptor; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.nodes.RNode; +import com.oracle.truffle.r.runtime.nodes.RSyntaxFunction; +import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; final class FunctionPrinter extends AbstractValuePrinter<RFunction> { @@ -75,9 +78,14 @@ final class FunctionPrinter extends AbstractValuePrinter<RFunction> { out.print(rBuiltin.getName()); out.print("\")"); } else { - final boolean useSource = printCtx.parameters().getUseSource(); - String source = ((RRootNode) operand.getTarget().getRootNode()).getSourceCode(); - if (source == null || !useSource) { + String source = null; + if (printCtx.parameters().getUseSource()) { + SourceSection sourceSection = ((RSyntaxFunction) operand.getRootNode()).getLazySourceSection(); + if (sourceSection != null && sourceSection != RSyntaxNode.LAZY_DEPARSE) { + source = sourceSection.getCode(); + } + } + if (source == null) { source = RDeparse.deparse(operand); } REnvironment env = RArguments.getEnvironment(operand.getEnclosingFrame()); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/S4ObjectPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/S4ObjectPrinter.java index b97c2ce73a9f1d9c34be5e0bd899e93f4edfde28..2807fa516e19ee783ca295440462030b83e552b4 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/S4ObjectPrinter.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/S4ObjectPrinter.java @@ -44,8 +44,10 @@ final class S4ObjectPrinter implements ValuePrinter<RS4Object> { public void print(RS4Object object, PrintContext printCtx) throws IOException { final PrintWriter out = printCtx.output(); out.print("<S4 Type Object>"); - for (RAttribute attr : object.getAttributes()) { - printAttribute(attr, printCtx); + if (object.getAttributes() != null) { + for (RAttribute attr : object.getAttributes()) { + printAttribute(attr, printCtx); + } } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java index 7a62c4fc65ad83af7ccc6bf359d644c292c4f581..4b35745a57d38575a5f0b42a2bcb630315bdc1bc 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java @@ -23,7 +23,6 @@ package com.oracle.truffle.r.nodes; import java.util.List; -import java.util.Map; import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.Truffle; @@ -56,6 +55,7 @@ import com.oracle.truffle.r.runtime.FastROptions; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.FastPathFactory; import com.oracle.truffle.r.runtime.data.REmpty; +import com.oracle.truffle.r.runtime.data.RShareable; import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor; import com.oracle.truffle.r.runtime.nodes.EvaluatedArgumentsVisitor; import com.oracle.truffle.r.runtime.nodes.RCodeBuilder; @@ -67,23 +67,11 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; /** * This class can be used to build fragments of Truffle AST that correspond to R language * constructs: calls, lookups, constants and functions. - * - * Additionally, this class has helper functions to issue (parser) warnings and - * */ public final class RASTBuilder implements RCodeBuilder<RSyntaxNode> { - private final Map<String, Object> constants; private CodeBuilderContext context = CodeBuilderContext.DEFAULT; - public RASTBuilder() { - this.constants = null; - } - - public RASTBuilder(Map<String, Object> constants) { - this.constants = constants; - } - @Override public RSyntaxNode call(SourceSection source, RSyntaxNode lhs, List<Argument<RSyntaxNode>> args) { if (lhs instanceof RSyntaxLookup) { @@ -105,6 +93,15 @@ public final class RASTBuilder implements RCodeBuilder<RSyntaxNode> { } } else if (args.size() == 2) { switch (symbol) { + case "$": + case "@": + if (args.get(1).value instanceof RSyntaxLookup) { + RSyntaxLookup lookup = (RSyntaxLookup) args.get(1).value; + // FastR differs from GNUR: we only use string constants to represent + // field and slot lookups, while GNUR uses symbols + args.set(1, RCodeBuilder.argument(args.get(1).source, args.get(1).name, constant(lookup.getLazySourceSection(), lookup.getIdentifier()))); + } + break; case "while": return new WhileNode(source, lhsLookup, args.get(0).value, args.get(1).value); case "if": @@ -255,6 +252,12 @@ public final class RASTBuilder implements RCodeBuilder<RSyntaxNode> { if (value instanceof String && !RRuntime.isNA((String) value)) { return ConstantNode.create(source, ((String) value).intern()); } else { + if (value instanceof RShareable) { + RShareable shareable = (RShareable) value; + if (!shareable.isSharedPermanent()) { + return ConstantNode.create(source, shareable.makeSharedPermanent()); + } + } return ConstantNode.create(source, value); } } @@ -274,12 +277,6 @@ public final class RASTBuilder implements RCodeBuilder<RSyntaxNode> { @Override public RSyntaxNode lookup(SourceSection source, String symbol, boolean functionLookup) { assert source != null; - if (constants != null && symbol.startsWith("C")) { - Object object = constants.get(symbol); - if (object != null) { - return ConstantNode.create(source, object); - } - } if (!functionLookup) { int index = getVariadicComponentIndex(symbol); if (index != -1) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RRootNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RRootNode.java index d59fc7e3ff22afcb38af5fb37c567cdae6c0e8ef..eb785b3c7cc1cda98117c71df3e407934d3390c2 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RRootNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RRootNode.java @@ -22,7 +22,6 @@ */ package com.oracle.truffle.r.nodes; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.frame.FrameDescriptor; import com.oracle.truffle.api.frame.VirtualFrame; @@ -69,36 +68,37 @@ public abstract class RRootNode extends RootNode implements HasSignature { } } + @Override public abstract RootCallTarget duplicateWithNewFrameDescriptor(); - protected void verifyEnclosingAssumptions(VirtualFrame vf) { + protected final void verifyEnclosingAssumptions(VirtualFrame vf) { RArguments.setIsIrregular(vf, irregularFrameProfile.profile(RArguments.getIsIrregular(vf))); } /** * @return The number of parameters this functions expects */ - public int getParameterCount() { + public final int getParameterCount() { return formalArguments.getSignature().getLength(); } /** * @return {@link #formalArguments} */ - public FormalArguments getFormalArguments() { + public final FormalArguments getFormalArguments() { return formalArguments; } @Override - public ArgumentsSignature getSignature() { + public final ArgumentsSignature getSignature() { return formalArguments.getSignature(); } - public FastPathFactory getFastPath() { + public final FastPathFactory getFastPath() { return fastPath; } - public void setFastPath(FastPathFactory fastPath) { + public final void setFastPath(FastPathFactory fastPath) { this.fastPath = fastPath; } @@ -110,16 +110,6 @@ public abstract class RRootNode extends RootNode implements HasSignature { public abstract RBuiltinFactory getBuiltin(); - @TruffleBoundary - public String getSourceCode() { - SourceSection ss = getSourceSection(); - if (ss != null) { - return ss.getCode(); - } else { - return null; - } - } - @Override public boolean isCloningAllowed() { return true; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinRootNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinRootNode.java index 559a17359f24bb6c206ec009e4ad06b87e768f66..ea86da6f090ada1bea4c02162a1939ddb0e4f6df 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinRootNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinRootNode.java @@ -117,11 +117,6 @@ public final class RBuiltinRootNode extends RRootNode { throw RInternalError.shouldNotReachHere("set containsDispatch on builtin " + factory.getName()); } - @Override - public String getSourceCode() { - throw RInternalError.shouldNotReachHere(); - } - @Override public String getName() { return "RBuiltin(" + builtin + ")"; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionExpressionNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionExpressionNode.java index 472020d8bcd90a4d6b26db4d23e37fa2ec1496ae..e0c9f9eb525f116bfd2cf38921a8320f3e12bfb0 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionExpressionNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionExpressionNode.java @@ -84,7 +84,7 @@ public final class FunctionExpressionNode extends RSourceSectionNode implements } initialized = true; } - RFunction func = RDataFactory.createFunction(RFunction.NO_NAME, callTarget, null, matFrame); + RFunction func = RDataFactory.createFunction(RFunction.NO_NAME, RFunction.NO_NAME, callTarget, null, matFrame); RInstrumentation.checkDebugRequested(func); return func; } diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/CallRFFIHelper.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/CallRFFIHelper.java index fb1091c71e64335b1695b1dc4e444ae31861f7e2..67a99f67b5fc0856cee7696e6d8e8554def52ada 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/CallRFFIHelper.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/CallRFFIHelper.java @@ -1153,7 +1153,7 @@ public class CallRFFIHelper { try { Source source = RSource.fromTextInternal(textString, RSource.Internal.R_PARSEVECTOR); - RExpression exprs = RContext.getEngine().parse(null, source); + RExpression exprs = RContext.getEngine().parse(source); return new ParseResult(ParseStatus.PARSE_OK.ordinal(), exprs); } catch (ParseException ex) { // TODO incomplete diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/HasSignature.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/HasSignature.java index ae2c743fbe29e0bc890841abc4a6f4896f9c0096..7ae86acaf1f35dba75a77d4895a44a81a8c4ab25 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/HasSignature.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/HasSignature.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, 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 @@ -22,6 +22,10 @@ */ package com.oracle.truffle.r.runtime; +import com.oracle.truffle.api.RootCallTarget; + public interface HasSignature { ArgumentsSignature getSignature(); + + RootCallTarget duplicateWithNewFrameDescriptor(); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RChannel.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RChannel.java index 0fec763e0e56036ee7fb48ae964ffcfafebab476..37282478572cb84bfb6ea1a8196b73037f5bccbe 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RChannel.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RChannel.java @@ -23,14 +23,12 @@ package com.oracle.truffle.r.runtime; import java.io.IOException; -import java.util.HashMap; -import java.util.Map; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.Semaphore; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.frame.MaterializedFrame; -import com.oracle.truffle.api.source.Source; import com.oracle.truffle.r.runtime.conn.RConnection; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RAttributable; @@ -38,18 +36,19 @@ import com.oracle.truffle.r.runtime.data.RAttributeStorage; import com.oracle.truffle.r.runtime.data.RAttributes; import com.oracle.truffle.r.runtime.data.RAttributes.RAttribute; import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RExpression; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RPromise; +import com.oracle.truffle.r.runtime.data.RPromise.Closure; +import com.oracle.truffle.r.runtime.data.RPromise.PromiseState; import com.oracle.truffle.r.runtime.data.RShareable; import com.oracle.truffle.r.runtime.data.RUnboundValue; import com.oracle.truffle.r.runtime.env.REnvironment; +import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor; import com.oracle.truffle.r.runtime.env.frame.REnvTruffleFrameAccess; -import com.oracle.truffle.r.runtime.gnur.SEXPTYPE; +import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; /** * Implementation of a channel abstraction used for communication between parallel contexts in @@ -272,9 +271,9 @@ public class RChannel { private final Object env; private final Object value; - private final byte[] serializedExpr; + private final RSyntaxElement serializedExpr; - public SerializedPromise(Object env, Object value, byte[] serializedExpr) { + public SerializedPromise(Object env, Object value, RSyntaxElement serializedExpr) { this.env = env; this.value = value; this.serializedExpr = serializedExpr; @@ -288,7 +287,7 @@ public class RChannel { return value; } - public byte[] getSerializedExpr() { + public RSyntaxElement getSerializedExpr() { return serializedExpr; } @@ -297,9 +296,9 @@ public class RChannel { protected static class SerializedFunction { private final RAttributes attributes; private final Object env; - private final byte[] serializedDef; + private final RFunction serializedDef; - public SerializedFunction(RAttributes attributes, Object env, byte[] serializedDef) { + public SerializedFunction(RAttributes attributes, Object env, RFunction serializedDef) { this.attributes = attributes; this.env = env; this.serializedDef = serializedDef; @@ -313,7 +312,7 @@ public class RChannel { return env; } - public byte[] getSerializedDef() { + public RFunction getSerializedDef() { return serializedDef; } } @@ -417,22 +416,20 @@ public class RChannel { private SerializedPromise convertPrivatePromise(Object msg) throws IOException { RPromise p = (RPromise) msg; - byte[] serializedPromiseRep = RSerialize.serializePromiseRep(p); if (p.isEvaluated()) { - return new SerializedPromise(RNull.instance, p.getValue(), serializedPromiseRep); + return new SerializedPromise(RNull.instance, p.getValue(), p.getClosure().getExpr().asRSyntaxNode()); } else { REnvironment env = p.getFrame() == null ? REnvironment.globalEnv() : REnvironment.frameToEnvironment(p.getFrame()); - return new SerializedPromise(convertPrivate(env), RUnboundValue.instance, serializedPromiseRep); + return new SerializedPromise(convertPrivate(env), RUnboundValue.instance, p.getClosure().getExpr().asRSyntaxNode()); } } private SerializedFunction convertPrivateFunction(Object msg) throws IOException { RFunction fn = (RFunction) msg; - byte[] serializedFunctionDef = RSerialize.serializeFunctionNonEnv(fn); Object env = convertPrivate(REnvironment.frameToEnvironment(fn.getEnclosingFrame())); RAttributes attributes = fn.getAttributes(); - return new SerializedFunction(attributes == null ? null : createShareableSlow(attributes, true), env, serializedFunctionDef); + return new SerializedFunction(attributes == null ? null : createShareableSlow(attributes, true), env, fn); } private Object convertPrivateAttributable(Object msg) throws IOException { @@ -629,27 +626,28 @@ public class RChannel { @TruffleBoundary private RPromise unserializePromise(SerializedPromise p) throws IOException { - Map<String, Object> constants = new HashMap<>(); - String deparse = RDeparse.deparseDeserialize(constants, RSerialize.unserialize(p.getSerializedExpr(), null, null, null)); - Source source = RSource.fromPackageTextInternal(deparse, null); - RExpression expr = RContext.getEngine().parse(constants, source); - Object env = p.getEnv(); - if (env != RNull.instance) { - env = unserializeObject(env); + Closure closure = Closure.create(RContext.getASTBuilder().process(p.getSerializedExpr()).asRNode()); + if (p.getValue() == RUnboundValue.instance) { + Object environment = p.getEnv(); + if (environment != RNull.instance) { + environment = unserializeObject(environment); + } + REnvironment env = environment == RNull.instance ? REnvironment.baseEnv() : (REnvironment) environment; + return RDataFactory.createPromise(PromiseState.Explicit, closure, env.getFrame()); + } else { + return RDataFactory.createEvaluatedPromise(closure, p.getValue()); } - return RSerialize.unserializePromise(expr, env, p.getValue()); } @TruffleBoundary private RFunction unserializeFunction(SerializedFunction f) throws IOException { - Map<String, Object> constants = new HashMap<>(); - RPairList l = (RPairList) RSerialize.unserialize(f.getSerializedDef(), null, null, null); - // seems like the best (only) way to make deparser see a correct pair list type here - RPairList closxpList = RDataFactory.createPairList(l.car(), l.cdr(), RNull.instance, SEXPTYPE.CLOSXP); - String deparse = RDeparse.deparseDeserialize(constants, closxpList); + RFunction fun = f.getSerializedDef(); REnvironment env = (REnvironment) unserializeObject(f.getEnv()); MaterializedFrame enclosingFrame = env.getFrame(); - RFunction fn = RContext.getEngine().parseFunction(constants, null, RSource.fromTextInternal(deparse, RSource.Internal.PAIRLIST_DEPARSE), enclosingFrame); + HasSignature root = (HasSignature) fun.getTarget().getRootNode(); + RootCallTarget target = root.duplicateWithNewFrameDescriptor(); + FrameSlotChangeMonitor.initializeEnclosingFrame(target.getRootNode().getFrameDescriptor(), enclosingFrame); + RFunction fn = RDataFactory.createFunction(fun.getName(), fun.getPackageName(), target, null, enclosingFrame); RAttributes attributes = f.getAttributes(); if (attributes != null) { assert fn.getAttributes() == null; @@ -685,11 +683,11 @@ public class RChannel { if (newVal != val) { // class attribute is a string vector which should be always shared assert !a.getName().equals(RRuntime.CLASS_ATTR_KEY); - // TODO: this is a bit brittle as it relies on the iterator to work - // correctly in - // the - // face of updates (which it does under current implementation of - // attributes) + /* + * TODO: this is a bit brittle as it relies on the iterator to work correctly in + * the face of updates (which it does under current implementation of + * attributes) + */ attributable.setAttr(a.getName(), newVal); } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java index 81bedb07ca94d3596a40f79a3ad038db89f924f2..8c0c3cbeb5949584fa1086469c6f9a6e2531cb23 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java @@ -15,9 +15,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; -import java.util.Map; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.source.Source; @@ -43,6 +41,7 @@ import com.oracle.truffle.r.runtime.data.RS4Object; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.RTypedValue; +import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractListVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @@ -58,18 +57,6 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxVisitor; /** * Deparsing R objects. - * - * There are two distinct clients of this class: - * <ul> - * <li>{@code RSerialize} when it needs to convert an unserialized GnuR {@code pairlist} instance - * that denotes a closure into an {@link RFunction} which is, currently, done by deparsing and - * reparsing the value.</li> - * <li>The {@code deparse} builtin.</li> - * </ul> - * - * Much of the code here is related to case 1, which would be unnecessary if unserialize created - * ASTs for language elements directly rather than via deparse/parse. The deparsing of ASTs is - * handled in {@code RASTDeparse} via the {@link RRuntimeASTAccess} interface. */ public class RDeparse { @@ -161,7 +148,7 @@ public class RDeparse { } } - @CompilationFinal private static final Func[] FUNCTAB = new Func[]{ + private static final Func[] FUNCTAB = new Func[]{ new Func("+", null, new PPInfo(PP.BINARY, PREC_SUM, false)), new Func("-", null, new PPInfo(PP.BINARY, PREC_SUM, false)), new Func("*", null, new PPInfo(PP.BINARY, PREC_PROD, false)), @@ -223,16 +210,6 @@ public class RDeparse { return len > 0 && op.charAt(0) == '%' && op.charAt(len - 1) == '%'; } - /** - * Ensure that {@code node} has a {@link SourceSection} by deparsing if necessary. - */ - public static void ensureSourceSection(RSyntaxElement node) { - SourceSection ss = node.getLazySourceSection(); - if (ss == RSyntaxNode.LAZY_DEPARSE) { - new DeparseVisitor(true, RDeparse.MAX_Cutoff, false, -1, 0, null).append(node).fixupSources(); - } - } - private static Func isInfixOperatorNode(RSyntaxElement element) { if (element instanceof RSyntaxCall) { RSyntaxElement lhs = ((RSyntaxCall) element).getSyntaxLHS(); @@ -285,14 +262,11 @@ public class RDeparse { private int indent = 0; private int lastLineStart = 0; - private final Map<String, Object> constants; - - DeparseVisitor(boolean storeSource, int cutoff, boolean backtick, int opts, int nlines, Map<String, Object> constants) { + DeparseVisitor(boolean storeSource, int cutoff, boolean backtick, int opts, int nlines) { this.cutoff = cutoff; this.backtick = backtick; this.opts = opts; this.nlines = nlines; - this.constants = constants; this.sources = storeSource ? new ArrayList<>() : null; } @@ -564,71 +538,9 @@ public class RDeparse { } @Override - @SuppressWarnings("try") protected Void visit(RSyntaxConstant constant) { // coerce scalar values to vectors and unwrap data frames and factors: - Object value = RRuntime.asAbstractVector(constant.getValue()); - - if (constants != null && !(value instanceof RAbstractVector || value instanceof RNull)) { - String name = "C.." + constants.size(); - constants.put(name, value); - append(name); - return null; - } - - if (value instanceof RExpression) { - append("expression(").appendListContents((RExpression) value).append(')'); - } else if (value instanceof RAbstractListVector) { - RAbstractListVector obj = (RAbstractListVector) value; - try (C c = withAttributes(obj)) { - append("list(").appendListContents(obj).append(')'); - } - } else if (value instanceof RAbstractVector) { - RAbstractVector obj = (RAbstractVector) value; - try (C c = withAttributes(obj)) { - appendVector((RAbstractVector) value); - } - } else if (value instanceof RNull) { - append("NULL"); - } else if (value instanceof RFunction) { - RFunction f = (RFunction) value; - if (f.isBuiltin()) { - append(".Primitive(\"").append(f.getName()).append("\")"); - } else { - append(RContext.getRRuntimeASTAccess().getSyntaxFunction(f)); - } - } else if (value instanceof RPairList) { - RPairList pl = (RPairList) value; - assert pl.getType() == SEXPTYPE.LISTSXP; - append("pairlist("); - Arguments<RSyntaxElement> arguments = wrapArguments(pl); - appendArgs(arguments.getSignature(), arguments.getArguments(), 0, false); - append(')'); - } else if (value instanceof RS4Object) { - RS4Object s4Obj = (RS4Object) value; - Object clazz = s4Obj.getAttr("class"); - String className = clazz == null ? "S4" : RRuntime.toString(RRuntime.asStringLengthOne(clazz)); - append("new(\"").append(className).append('\"'); - try (C c = indent()) { - printline(); - if (s4Obj.getAttributes() != null) { - for (RAttribute att : s4Obj.getAttributes()) { - if (!"class".equals(att.getName())) { - append(", ").append(att.getName()).append(" = ").process(att.getValue()).printline(); - } - } - } - } - append(')'); - } else if (value instanceof RExternalPtr) { - append("<pointer: 0x").append(Long.toHexString(((RExternalPtr) value).getAddr())).append('>'); - } else if (value instanceof REnvironment) { - append("<environment>"); - } else if (value instanceof TruffleObject) { - append("<truffle object>"); - } else { - throw RInternalError.shouldNotReachHere("unexpected: " + value); - } + appendConstant(constant.getValue()); return null; } @@ -644,24 +556,10 @@ public class RDeparse { @Override protected Void visit(RSyntaxFunction function) { - append("function ("); + append("function("); appendArgs(function.getSyntaxSignature(), function.getSyntaxArgumentDefaults(), 0, true); append(") "); - RSyntaxElement body = function.getSyntaxBody(); - boolean newline = true; - if (body instanceof RSyntaxCall) { - RSyntaxCall c = (RSyntaxCall) body; - if (c.getSyntaxLHS() instanceof RSyntaxLookup) { - RSyntaxLookup l = (RSyntaxLookup) c.getSyntaxLHS(); - if ("{".equals(l.getIdentifier())) { - newline = false; - } - } - } - if (newline) { - printline(); - } - append(body); + appendFunctionBody(function.getSyntaxBody()); return null; } } @@ -669,7 +567,10 @@ public class RDeparse { private void appendWithParens(RSyntaxElement arg, PPInfo mainOp, boolean isLeft) { Func func = isInfixOperatorNode(arg); boolean needsParens = false; - if (func != null) { + if (func == null) { + // put parens around complex values + needsParens = !isLeft && arg instanceof RSyntaxConstant && ((RSyntaxConstant) arg).getValue() instanceof RAbstractComplexVector; + } else { PPInfo arginfo = func.info; switch (arginfo.kind) { case ASSIGN: @@ -713,22 +614,112 @@ public class RDeparse { } } + @SuppressWarnings("try") + private DeparseVisitor appendConstant(Object originalValue) { + Object value = RRuntime.asAbstractVector(originalValue); + if (value instanceof RExpression) { + append("expression(").appendListContents((RExpression) value).append(')'); + } else if (value instanceof RAbstractListVector) { + RAbstractListVector obj = (RAbstractListVector) value; + try (C c = withAttributes(obj)) { + append("list(").appendListContents(obj).append(')'); + } + } else if (value instanceof RAbstractVector) { + RAbstractVector obj = (RAbstractVector) value; + try (C c = withAttributes(obj)) { + appendVector((RAbstractVector) value); + } + } else if (value instanceof RNull) { + append("NULL"); + } else if (value instanceof RFunction) { + RFunction f = (RFunction) value; + if (f.isBuiltin()) { + append(".Primitive(\"").append(f.getName()).append("\")"); + } else { + RSyntaxFunction function = (RSyntaxFunction) f.getRootNode(); + append("function ("); + appendArgs(function.getSyntaxSignature(), function.getSyntaxArgumentDefaults(), 0, true); + append(") "); + appendFunctionBody(function.getSyntaxBody()); + } + } else if (value instanceof RPairList) { + RPairList arglist = (RPairList) value; + assert arglist.getType() == SEXPTYPE.LISTSXP; + append("pairlist("); + int i = 0; + boolean lbreak = false; + while (arglist != null) { + if (i++ > 0) { + append(", "); + } + lbreak = linebreak(lbreak); + if (arglist.getTag() != RNull.instance) { + String argName = ((RSymbol) arglist.getTag()).getName(); + if (!argName.isEmpty()) { + append(argName).append(" = "); + } + } + appendValue(arglist.car()); + + arglist = next(arglist); + } + append(')'); + } else if (value instanceof RS4Object) { + RS4Object s4Obj = (RS4Object) value; + Object clazz = s4Obj.getAttr("class"); + String className = clazz == null ? "S4" : RRuntime.toString(RRuntime.asStringLengthOne(clazz)); + append("new(\"").append(className).append('\"'); + try (C c = indent()) { + printline(); + if (s4Obj.getAttributes() != null) { + for (RAttribute att : s4Obj.getAttributes()) { + if (!"class".equals(att.getName())) { + append(", ").append(att.getName()).append(" = ").appendValue(att.getValue()).printline(); + } + } + } + } + append(')'); + } else if (value instanceof RExternalPtr) { + append("<pointer: 0x").append(Long.toHexString(((RExternalPtr) value).getAddr())).append('>'); + } else if (value instanceof REnvironment) { + append("<environment>"); + } else if (value instanceof TruffleObject) { + append("<truffle object>"); + } else { + throw RInternalError.shouldNotReachHere("unexpected: " + value); + } + return this; + } + + private DeparseVisitor appendFunctionBody(RSyntaxElement body) { + boolean newline = true; + if (body instanceof RSyntaxCall) { + RSyntaxCall c = (RSyntaxCall) body; + if (c.getSyntaxLHS() instanceof RSyntaxLookup) { + RSyntaxLookup l = (RSyntaxLookup) c.getSyntaxLHS(); + if ("{".equals(l.getIdentifier())) { + newline = false; + } + } + } + if (newline) { + printline(); + } + return append(body); + } + private DeparseVisitor appendArgs(ArgumentsSignature signature, RSyntaxElement[] args, int start, boolean formals) { boolean lbreak = false; for (int i = start; i < args.length; i++) { + if (i > start) { + append(", "); + } lbreak = linebreak(lbreak); RSyntaxElement argument = args[i]; - if (argument instanceof RSyntaxLookup && ((RSyntaxLookup) argument).getIdentifier().isEmpty()) { - argument = null; - } - if (argument instanceof RSyntaxConstant && ((RSyntaxConstant) argument).getValue() instanceof REmpty) { - argument = null; - } String name = signature.getName(i); - if (name != null && name.isEmpty()) { - name = null; - } - if (name != null) { + + if (name != null && !name.isEmpty()) { if (isValidName(name)) { append(name); } else { @@ -739,11 +730,14 @@ public class RDeparse { } } if (argument != null) { + if (argument instanceof RSyntaxLookup && ((RSyntaxLookup) argument).getIdentifier().isEmpty()) { + continue; + } + if (argument instanceof RSyntaxConstant && ((RSyntaxConstant) argument).getValue() instanceof REmpty) { + continue; + } append(argument); } - if (i != args.length - 1) { - append(", "); - } } if (lbreak) { indent--; @@ -751,100 +745,31 @@ public class RDeparse { return this; } - private DeparseVisitor process(Object v) { + private DeparseVisitor appendValue(Object v) { assert v != null; - assert RRuntime.asAbstractVector(v) instanceof RTypedValue : v.getClass(); assert !(v instanceof RSyntaxElement) : v.getClass(); - RSyntaxElement element = wrap(v, false); - if (!quoteExpressions() || element instanceof RSyntaxConstant) { - append(element); - } else { - append("quote("); - append(element); - append(')'); - } - return this; - } - - private static RSyntaxElement wrap(Object v, boolean isCallLHS) { Object value = RRuntime.asAbstractVector(v); + assert value instanceof RTypedValue : v.getClass(); + + RSyntaxElement element; if (value instanceof RSymbol) { - return RSyntaxLookup.createDummyLookup(RSyntaxNode.INTERNAL, ((RSymbol) value).getName(), isCallLHS); + element = RSyntaxLookup.createDummyLookup(RSyntaxNode.INTERNAL, ((RSymbol) value).getName(), false); } else if (value instanceof RLanguage) { - return ((RLanguage) value).getRep().asRSyntaxNode(); - } else if (value instanceof RPairList) { - RPairList pl = (RPairList) value; - switch (pl.getType()) { - case LANGSXP: - return wrapCall(pl); - case CLOSXP: - return wrapFunctionExpression(pl); - default: - throw RInternalError.shouldNotReachHere("sexptype: " + pl.getType()); - } + element = ((RLanguage) value).getRep().asRSyntaxNode(); } else if (value instanceof RMissing) { - return RSyntaxLookup.createDummyLookup(null, "", false); + element = RSyntaxLookup.createDummyLookup(null, "", false); } else { - return RSyntaxConstant.createDummyConstant(null, value); - } - } - - private static RSyntaxElement wrapCall(RPairList pl) { - Object car = pl.car(); - if (car instanceof RSymbol && ((RSymbol) car).getName().equals("function")) { - RPairList fun = (RPairList) pl.cdr(); - return wrapFunctionExpression(fun); + return appendConstant(value); } - RSyntaxElement lhs = wrap(car, true); - - Arguments<RSyntaxElement> args = wrapArguments(pl.cdr()); - return RSyntaxCall.createDummyCall(null, lhs, args.getSignature(), args.getArguments()); - } - - private static RSyntaxElement wrapFunctionExpression(RPairList fun) { - // assert fun.getTag() == RNull.instance : "function expression with non-null - // environment"; - Arguments<RSyntaxElement> args = wrapArguments(fun.car()); - RSyntaxElement body; - Object cdr = fun.cdr(); - if (cdr instanceof RPairList) { - RPairList pl = (RPairList) cdr; - if (pl.getType() == SEXPTYPE.BCODESXP) { - RAbstractListVector list = (RAbstractListVector) fun.cddr(); - body = wrap(list.getDataAtAsObject(0), false); - } else if (pl.getType() == SEXPTYPE.LISTSXP) { - assert pl.cdr() == RNull.instance || (pl.cadr() == RNull.instance && pl.cddr() == RNull.instance); - body = wrap(pl.car(), false); - } else { - assert pl.getType() == SEXPTYPE.LANGSXP; - body = wrap(pl, false); - } + if (!quoteExpressions() || element instanceof RSyntaxConstant) { + append(element); } else { - body = wrap(cdr, false); - } - - return RSyntaxFunction.createDummyFunction(null, args.getSignature(), args.getArguments(), body, null); - } - - private static Arguments<RSyntaxElement> wrapArguments(Object args) { - RPairList arglist = args instanceof RNull ? null : (RPairList) args; - ArrayList<RSyntaxElement> argElements = new ArrayList<>(); - ArrayList<String> argNames = new ArrayList<>(); - while (arglist != null) { - Object argTag = arglist.getTag(); - if (argTag != null && argTag != RNull.instance) { - String rs = ((RSymbol) arglist.getTag()).getName(); - argNames.add(rs); - } else { - argNames.add(null); - } - argElements.add(wrap(arglist.car(), false)); - arglist = next(arglist); + append("quote("); + append(element); + append(')'); } - RSyntaxElement[] arguments = argElements.toArray(new RSyntaxElement[argElements.size()]); - ArgumentsSignature signature = ArgumentsSignature.get(argNames.toArray(new String[argNames.size()])); - return Arguments.create(arguments, signature); + return this; } private static RPairList next(RPairList pairlist) { @@ -952,12 +877,11 @@ public class RDeparse { append(", "); } lbreak = linebreak(lbreak); - String sname = snames == null ? null : snames.getDataAt(i); - if (snames != null && ((sname = snames.getDataAt(i)) != null)) { - append(sname); + if (snames != null) { + append(snames.getDataAt(i)); append(" = "); } - append(wrap(v.getDataAtAsObject(i), false)); + appendValue(v.getDataAtAsObject(i)); } if (lbreak) { indent--; @@ -1021,7 +945,7 @@ public class RDeparse { append(dotName); } append(" = "); - process(attr.getValue()); + appendValue(attr.getValue()); append(')'); } } @@ -1033,36 +957,30 @@ public class RDeparse { } } - /** - * Version for use by {@code RSerialize} to convert a CLOSXP/LANGSXP/PROMSXP into a parseable - * string. - */ - @TruffleBoundary - public static String deparseDeserialize(Map<String, Object> constants, Object obj) { - Object root = obj; - if (root instanceof RPairList) { - RPairList pl = (RPairList) root; - if (pl.getType() == SEXPTYPE.BCODESXP) { - RAbstractListVector list = (RAbstractListVector) pl.cdr(); - root = list.getDataAtAsObject(0); - } - } - return new DeparseVisitor(false, 80, true, SHOWATTRIBUTES, -1, constants).process(root).getContents(); - } - @TruffleBoundary public static String deparseSyntaxElement(RSyntaxElement element) { - return new DeparseVisitor(false, RDeparse.MAX_Cutoff, true, 0, -1, null).append(element).getContents(); + return new DeparseVisitor(false, RDeparse.MAX_Cutoff, true, 0, -1).append(element).getContents(); } @TruffleBoundary - public static String deparse(Object expr) { - return new DeparseVisitor(false, RDeparse.MAX_Cutoff, true, 0, -1, null).process(expr).getContents(); + public static String deparse(Object value) { + return new DeparseVisitor(false, RDeparse.MAX_Cutoff, true, 0, -1).appendValue(value).getContents(); } @TruffleBoundary public static String deparse(Object expr, int cutoff, boolean backtick, int opts, int nlines) { - return new DeparseVisitor(false, cutoff, backtick, opts, nlines, null).process(expr).getContents(); + return new DeparseVisitor(false, cutoff, backtick, opts, nlines).appendValue(expr).getContents(); + } + + /** + * Ensure that {@code node} has a {@link SourceSection} by deparsing if necessary. + */ + public static void ensureSourceSection(RSyntaxNode node) { + SourceSection ss = node.getLazySourceSection(); + if (ss == RSyntaxNode.LAZY_DEPARSE) { + new DeparseVisitor(true, RDeparse.MAX_Cutoff, false, -1, 0).append(node).fixupSources(); + assert node.getLazySourceSection() != RSyntaxNode.LAZY_DEPARSE; + } } private static String quotify(String name, char qc) { @@ -1073,7 +991,7 @@ public class RDeparse { sb.append(qc); for (int i = 0; i < name.length(); i++) { char ch = name.charAt(i); - if (ch == '\\') { + if (ch == '\\' || ch == '`') { sb.append(ch); } sb.append(ch); @@ -1086,10 +1004,6 @@ public class RDeparse { private static final HashSet<String> keywords = new HashSet<>(Arrays.asList("NULL", "NA", "TRUE", "FALSE", "Inf", "NaN", "NA_integer_", "NA_real_", "NA_character_", "NA_complex_", "function", "while", "repeat", "for", "if", "in", "else", "next", "break", "...")); - private static boolean isKeyword(String name) { - return keywords.contains(name); - } - public static boolean isValidName(String name) { char ch = safeCharAt(name, 0); if (ch != '.' && !Character.isLetter(ch)) { @@ -1110,7 +1024,7 @@ public class RDeparse { if (name.equals("...")) { return true; } - if (isKeyword(name)) { + if (keywords.contains(name)) { return false; } return true; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RInternalCode.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RInternalCode.java index dc57b2b69c7cb57f9e09908765a1bbb1328e7d20..f47dda016857a979b6e7ece30d3ffc88a381de07 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RInternalCode.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RInternalCode.java @@ -23,7 +23,6 @@ package com.oracle.truffle.r.runtime; -import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -60,7 +59,7 @@ public final class RInternalCode { private REnvironment evaluate() { try { - RExpression parsedCode = context.getThisEngine().parse(Collections.emptyMap(), source); + RExpression parsedCode = context.getThisEngine().parse(source); REnvironment statsPackage = REnvironment.getRegisteredNamespace(context, basePackage); evaluatedEnvironment = RDataFactory.createNewEnv(null, true, 10); evaluatedEnvironment.setParent(statsPackage); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntimeASTAccess.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntimeASTAccess.java index db3d5c223ea2a3d048d1c06c8e9f4e46487d0262..7a4a01cd501f6eca13e219621a21fff3466dc094 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntimeASTAccess.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntimeASTAccess.java @@ -192,4 +192,6 @@ public interface RRuntimeASTAccess { String encodeComplex(RComplex x, int digits); + void checkDebugRequest(RFunction func); + } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java index d0817ba5237595ce31d44d938e5f70d1e61ec27c..5d7fa9e54034542e95439baf6d3b45d637edd077 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java @@ -13,29 +13,28 @@ package com.oracle.truffle.r.runtime; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; import java.lang.ref.WeakReference; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Arrays; import java.util.Deque; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; +import java.util.List; import java.util.Map; import java.util.WeakHashMap; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.frame.MaterializedFrame; -import com.oracle.truffle.api.source.Source; import com.oracle.truffle.r.runtime.conn.RConnection; -import com.oracle.truffle.r.runtime.context.Engine.ParseException; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RAttributable; @@ -67,14 +66,18 @@ import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.RTypedValue; import com.oracle.truffle.r.runtime.data.RUnboundValue; import com.oracle.truffle.r.runtime.data.RVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractListVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.env.REnvironment; +import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor; import com.oracle.truffle.r.runtime.gnur.SEXPTYPE; -import com.oracle.truffle.r.runtime.instrument.RPackageSource; -import com.oracle.truffle.r.runtime.nodes.RBaseNode; +import com.oracle.truffle.r.runtime.nodes.RCodeBuilder; import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; import com.oracle.truffle.r.runtime.nodes.RSyntaxConstant; import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; @@ -187,7 +190,7 @@ public class RSerialize { * {@code true} iff we are saving the source from the deparse of an unserialized function * (for debugging later). */ - private boolean saveDeparse; + boolean saveDeparse; /** * {@code ...getNamespace} in "namespace.R", used to callback to handle a @@ -324,26 +327,6 @@ public class RSerialize { return result; } - @TruffleBoundary - public static RPromise unserializePromise(RExpression expr, Object e, Object value) { - assert expr.getLength() == 1; - RBaseNode rep; - if (expr.getDataAt(0) instanceof RLanguage) { - RLanguage lang = (RLanguage) expr.getDataAt(0); - rep = lang.getRep(); - } else if (expr.getDataAt(0) instanceof RSymbol) { - rep = RContext.getASTBuilder().lookup(RSyntaxNode.SOURCE_UNAVAILABLE, ((RSymbol) expr.getDataAt(0)).getName(), false).asRNode(); - } else { - rep = RContext.getASTBuilder().constant(RSyntaxNode.SOURCE_UNAVAILABLE, expr.getDataAt(0)).asRNode(); - } - if (value == RUnboundValue.instance) { - REnvironment env = e == RNull.instance ? REnvironment.baseEnv() : (REnvironment) e; - return RDataFactory.createPromise(PromiseState.Explicit, Closure.create(rep), env.getFrame()); - } else { - return RDataFactory.createEvaluatedPromise(Closure.create(rep), value); - } - } - private static class Input extends Common { protected final PInputStream stream; @@ -360,13 +343,9 @@ public class RSerialize { protected String functionName; /** - * We need to know whether we are unserializing a {@link SEXPTYPE#CLOSXP} as we do not want - * convert embedded instances of {@link SEXPTYPE#LANGSXP} into ASTs. - */ - private int closureDepth; - /** - * For formula, the same logic applies as we only want to convert to an RFormula when - * langDepth is zero. + * We need to know whether we are unserializing a {@link SEXPTYPE#CLOSXP}, + * {@link SEXPTYPE#LANGSXP} or {@link SEXPTYPE#PROMSXP} as we do not want convert embedded + * instances of {@link SEXPTYPE#LANGSXP} into ASTs. */ private int langDepth; @@ -382,7 +361,6 @@ public class RSerialize { super(hook); this.packageName = packageName; this.functionName = functionName; - this.closureDepth = 0; byte[] buf = new byte[2]; is.read(buf); switch (buf[0]) { @@ -430,9 +408,8 @@ public class RSerialize { private void incDepth(SEXPTYPE type) { switch (type) { case CLOSXP: - closureDepth++; - break; case LANGSXP: + case PROMSXP: langDepth++; break; default: @@ -565,21 +542,11 @@ public class RSerialize { } Object carItem = readItem(); Object cdrItem = readItem(); - RPairList pairList = RDataFactory.createPairList(carItem, cdrItem, tagItem, type); - result = pairList; - if (attrItem != RNull.instance) { - /* - * TODO Currently we are losing attributes on CLOSXP (and LANGSXP) objects - * because this code places the attributes on the pairList and not on the - * RFunction object we eventually convert the pairlist into. - */ - setAttributes(pairList, attrItem); - } // Unlike GnuR the different types require some special treatment switch (type) { case CLOSXP: { - closureDepth--; + langDepth--; /* * Must convert the RPairList to a FastR AST. We could convert to an AST * directly, but it is easier and more robust to deparse and reparse. @@ -587,27 +554,19 @@ public class RSerialize { * level or not (and they are not always at the top in the default * packages) */ - RPairList rpl = (RPairList) result; if (FastROptions.debugMatches("printUclosure")) { - Debug.printClosure(rpl); + RPairList pairList = RDataFactory.createPairList(carItem, cdrItem, tagItem, type); + result = pairList; + if (attrItem != RNull.instance) { + setAttributes(pairList, attrItem); + } + Debug.printClosure(pairList); } - Map<String, Object> constants = new HashMap<>(); - String deparse = RDeparse.deparseDeserialize(constants, rpl); - try { - /* - * The tag of result is the enclosing environment (from - * NAMESPACESEXP) for the function. However the namespace is locked, - * so can't just eval there (and overwrite the promise), so we fix - * the enclosing frame up on return. - */ - MaterializedFrame enclosingFrame = ((REnvironment) rpl.getTag()).getFrame(); - RFunction func = parseFunction(constants, deparse, enclosingFrame, currentFunctionName); - - RAttributes.copyAttributes(func, rpl.getAttributes()); - result = func; - } catch (Throwable ex) { - throw new RInternalError(ex, "unserialize - failed to eval deparsed closure"); + RFunction func = PairlistDeserializer.processFunction(carItem, cdrItem, tagItem, currentFunctionName, packageName); + if (attrItem != RNull.instance) { + setAttributes(func, attrItem); } + result = func; break; } @@ -619,61 +578,69 @@ public class RSerialize { * the CLOSXP case, the entire structure is deparsed at the end. Ditto * for LANGSXP when specifying a formula */ - if (closureDepth == 0 && langDepth == 0) { - RPairList pl = (RPairList) result; - Map<String, Object> constants = new HashMap<>(); - String deparse = RDeparse.deparseDeserialize(constants, pl); - RExpression expr = parse(constants, deparse); - assert expr.getLength() == 1; - result = expr.getDataAt(0); - RAttributes attrs = pl.getAttributes(); - if (result instanceof RAttributable) { - RAttributes.copyAttributes((RAttributable) result, attrs); + if (langDepth == 0) { + RLanguage lang = PairlistDeserializer.processLanguage(carItem, cdrItem, tagItem); + if (attrItem != RNull.instance) { + setAttributes(lang, attrItem); + } + result = lang; + } else { + RPairList pairList = RDataFactory.createPairList(carItem, cdrItem, tagItem, type); + result = pairList; + if (attrItem != RNull.instance) { + setAttributes(pairList, attrItem); } } break; } case PROMSXP: { - RPairList pl = (RPairList) result; + langDepth--; /* * tag: environment for eval (or RNull if evaluated), car: value: * RUnboundValue if not evaluated, cdr: expression */ - Map<String, Object> constants = new HashMap<>(); - String deparse = RDeparse.deparseDeserialize(constants, pl.cdr()); - RExpression expr = parse(constants, deparse); - assert expr.getLength() == 1; - result = unserializePromise(expr, pl.getTag(), pl.car()); + result = PairlistDeserializer.processPromise(carItem, cdrItem, tagItem); break; } case DOTSXP: { - RPairList pl = (RPairList) result; - int len = pl.getLength(); + RPairList pairList = RDataFactory.createPairList(carItem, cdrItem, tagItem, type); + int len = pairList.getLength(); Object[] values = new Object[len]; String[] names = new String[len]; for (int i = 0; i < len; i++) { - values[i] = pl.car(); - if (pl.getTag() != RNull.instance) { - names[i] = ((RSymbol) pl.getTag()).getName(); + values[i] = pairList.car(); + if (pairList.getTag() != RNull.instance) { + names[i] = ((RSymbol) pairList.getTag()).getName(); } if (i < len - 1) { - pl = (RPairList) pl.cdr(); + pairList = (RPairList) pairList.cdr(); } } return new RArgsValuesAndNames(values, ArgumentsSignature.get(names)); } case LISTSXP: + RPairList pairList = RDataFactory.createPairList(carItem, cdrItem, tagItem, type); + result = pairList; + if (attrItem != RNull.instance) { + /* + * TODO Currently we are losing attributes on CLOSXP (and LANGSXP) + * objects because this code places the attributes on the pairList + * and not on the RFunction object we eventually convert the + * pairlist into. + */ + setAttributes(pairList, attrItem); + } break; } - if (!(result instanceof RScalar)) { - ((RTypedValue) result).setGPBits(levs); - } else { - // for now we only record S4-ness here, and in this case it shoud be 0 + if (result instanceof RScalar) { + // for now we only record S4-ness here, and in this case it should be 0 assert (levs == 0); + } else { + ((RTypedValue) result).setGPBits(levs); } return checkResult(result); } @@ -867,80 +834,6 @@ public class RSerialize { return result; } - private RExpression parse(Map<String, Object> constants, String deparseRaw) throws IOException { - try { - Source source = RSource.fromPackageTextInternal(deparseRaw, packageName); - return RContext.getEngine().parse(constants, source); - } catch (Throwable ex) { - /* - * Denotes a deparse/eval error, which is an unrecoverable bug, except in the - * special case where we are just saving package sources. - */ - saveDeparseResult(deparseRaw, true); - if (!contextState.saveDeparse) { - throw new RInternalError(ex, "internal deparse error - see file DEPARSE_ERROR"); - } else { - return null; - } - } - } - - private RFunction parseFunction(Map<String, Object> constants, String deparseRaw, MaterializedFrame enclosingFrame, String currentFunctionName) throws IOException { - try { - String sourcePath = null; - String deparse = deparseRaw; - /* - * To disambiguate identical saved deparsed files in different packages add a header - * line - */ - deparse = "# deparsed from package: " + packageName + "\n" + deparse; - if (contextState.saveDeparse) { - saveDeparseResult(deparse, false); - } else { - sourcePath = RPackageSource.lookup(deparse); - } - Source source; - String name; - if (sourcePath == null) { - source = RSource.fromPackageTextInternalWithName(deparse, packageName, currentFunctionName); - name = currentFunctionName; - } else { - source = RSource.fromFileName(deparse, sourcePath); - // Located a function source file from which we can retrieve the function name - name = RPackageSource.decodeName(sourcePath); - } - return RContext.getEngine().parseFunction(constants, name, source, enclosingFrame); - } catch (Throwable ex) { - /* - * Denotes a deparse/eval error, which is an unrecoverable bug, except in the - * special case where we are just saving package sources. - */ - saveDeparseResult(deparseRaw, true); - if (!contextState.saveDeparse) { - throw new RInternalError(ex, "internal deparse error - see file DEPARSE_ERROR"); - } else { - try { - return RContext.getEngine().parseFunction(constants, "", FAILED_DEPARSE_FUNCTION_SOURCE, enclosingFrame); - } catch (ParseException e) { - throw RInternalError.shouldNotReachHere(); - } - } - } - } - - private void saveDeparseResult(String deparse, boolean isError) throws IOException { - if (contextState.saveDeparse) { - RPackageSource.deparsed(deparse, isError); - } else if (isError) { - try (FileWriter wr = new FileWriter(new File(new File(REnvVars.rHome()), "DEPARSE" + (isError ? "_ERROR" : "")))) { - wr.write(deparse); - } - } - } - - private static final String FAILED_DEPARSE_FUNCTION = "function(...) stop(\"FastR error: proxy for lazily loaded function that did not deparse/parse\")"; - private static final Source FAILED_DEPARSE_FUNCTION_SOURCE = RSource.fromTextInternal(FAILED_DEPARSE_FUNCTION, RSource.Internal.DEPARSE_ERROR); - /** * GnuR uses a pairlist to represent attributes, whereas FastR uses the abstract RAttributes * class. FastR also uses different types to represent data/frame and factor which is @@ -1395,7 +1288,7 @@ public class RSerialize { public static final int ASCII_HEX = 2; public static final int BINARY = 3; - private static class Output extends Common { + private static final class Output extends Common { private State state; protected final POutputStream stream; @@ -2191,43 +2084,6 @@ public class RSerialize { } } - @TruffleBoundary - public static byte[] serializePromiseRep(RPromise promise) { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - try { - Output output = new Output(out, XDR, DEFAULT_VERSION, null); - State state = new PLState(output); - state.openPairList(); - new SerializeVisitor(state).accept(promise.getRep().asRSyntaxNode()); - Object res = state.closePairList(); - if (res instanceof RPairList) { - state.convertUnboundValues((RPairList) res); - } - output.serialize(state, res); - return out.toByteArray(); - } catch (IOException ex) { - throw RInternalError.shouldNotReachHere(); - } - } - - @TruffleBoundary - public static byte[] serializeFunctionNonEnv(RFunction fn) { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - try { - Output output = new Output(out, XDR, DEFAULT_VERSION, null); - State state = new PLState(output); - state.openPairList(SEXPTYPE.CLOSXP); - serializeFunctionDefinition(state, (RSyntaxFunction) fn.getRootNode()); - Object res = state.closePairList(); - // CLOSXP-type ensures that the list is not shrunk - state.convertUnboundValues((RPairList) res); - output.serialize(state, res); - return out.toByteArray(); - } catch (IOException ex) { - throw RInternalError.shouldNotReachHere(); - } - } - @TruffleBoundary public static void serialize(RConnection conn, Object obj, int type, int version, Object refhook) throws IOException { Output output = new Output(conn.getOutputStream(), type, version, (CallHook) refhook); @@ -2522,4 +2378,135 @@ public class RSerialize { state.setCdr(state.closePairList()); return state.closePairList(); } + + /** + * A collection of static functions that will transform a pairlist into an AST using the + * {@link RCodeBuilder}. + */ + private static final class PairlistDeserializer { + + public static RFunction processFunction(Object car, Object cdr, Object tag, String functionName, String packageName) { + // car == arguments, cdr == body, tag == environment + + REnvironment environment = (REnvironment) tag; + MaterializedFrame enclosingFrame = environment.getFrame(); + RootCallTarget callTarget = RContext.getASTBuilder().rootFunction(RSyntaxNode.LAZY_DEPARSE, processArguments(car), processBody(cdr), functionName); + + FrameSlotChangeMonitor.initializeEnclosingFrame(callTarget.getRootNode().getFrameDescriptor(), enclosingFrame); + RFunction func = RDataFactory.createFunction(functionName, packageName, callTarget, null, enclosingFrame); + + RContext.getRRuntimeASTAccess().checkDebugRequest(func); + + /* + * TODO: this is missing the code that registers sources with RPackageSource! + */ + return func; + } + + public static RLanguage processLanguage(Object car, Object cdr, Object tag) { + return RDataFactory.createLanguage(processCall(car, cdr, tag).asRNode()); + } + + public static RPromise processPromise(Object car, Object cdr, Object tag) { + // car == value, cdr == expression, tag == environment + + Closure closure = Closure.create(processBody(cdr).asRNode()); + if (car == RUnboundValue.instance) { + REnvironment env = tag == RNull.instance ? REnvironment.baseEnv() : (REnvironment) tag; + return RDataFactory.createPromise(PromiseState.Explicit, closure, env.getFrame()); + } else { + return RDataFactory.createEvaluatedPromise(closure, car); + } + } + + private static RSyntaxNode process(Object value, boolean isCallLHS) { + if (value instanceof RSymbol) { + return RContext.getASTBuilder().lookup(RSyntaxNode.LAZY_DEPARSE, ((RSymbol) value).getName(), isCallLHS); + } else if (value instanceof RPairList) { + RPairList pl = (RPairList) value; + switch (pl.getType()) { + case LANGSXP: + return processCall(pl.car(), pl.cdr(), pl.getTag()); + case CLOSXP: + return processFunctionExpression(pl.car(), pl.cdr(), pl.getTag()); + default: + throw RInternalError.shouldNotReachHere("unexpected SXP type: " + pl.getType()); + } + } else { + assert !(value instanceof RMissing) : "should be handled outside"; + assert !(value instanceof RLanguage) : "unexpected RLanguage constant in unserialize"; + + return RContext.getASTBuilder().constant(RSyntaxNode.LAZY_DEPARSE, unwrapScalarValues(value)); + } + } + + /** Convert single-element atomic vectors to their primitive counterparts. */ + private static Object unwrapScalarValues(Object value) { + if (value instanceof RAbstractVector) { + RAbstractVector vector = (RAbstractVector) value; + if (vector.getLength() == 1 && (vector.getAttributes() == null || vector.getAttributes().isEmpty())) { + if (vector instanceof RAbstractDoubleVector || vector instanceof RAbstractIntVector || vector instanceof RAbstractStringVector || + vector instanceof RAbstractLogicalVector || vector instanceof RAbstractRawVector || vector instanceof RAbstractComplexVector) { + return vector.getDataAtAsObject(0); + } + } + } + return value; + } + + private static RSyntaxNode processCall(Object car, Object cdr, @SuppressWarnings("unused") Object tag) { + if (car instanceof RSymbol && ((RSymbol) car).getName().equals("function")) { + RPairList function = (RPairList) cdr; + return processFunctionExpression(function.car(), function.cdr(), function.getTag()); + } + return RContext.getASTBuilder().call(RSyntaxNode.LAZY_DEPARSE, process(car, true), processArguments(cdr)); + } + + private static RSyntaxNode processFunctionExpression(Object car, Object cdr, @SuppressWarnings("unused") Object tag) { + // car == arguments, cdr == body + return RContext.getASTBuilder().function(RSyntaxNode.LAZY_DEPARSE, processArguments(car), processBody(cdr), null); + } + + private static List<RCodeBuilder.Argument<RSyntaxNode>> processArguments(Object args) { + List<RCodeBuilder.Argument<RSyntaxNode>> list = new ArrayList<>(); + + RPairList arglist = args instanceof RNull ? null : (RPairList) args; + while (arglist != null) { + // for each argument: tag == name, car == value + String name = arglist.getTag() == RNull.instance ? null : ((RSymbol) arglist.getTag()).getName(); + RSyntaxNode value = arglist.car() == RMissing.instance ? null : process(arglist.car(), false); + list.add(RCodeBuilder.argument(RSyntaxNode.LAZY_DEPARSE, name, value)); + arglist = next(arglist); + } + + return list; + } + + private static RPairList next(RPairList pairlist) { + if (pairlist.cdr() == RNull.instance) { + return null; + } else { + return (RPairList) pairlist.cdr(); + } + } + + private static RSyntaxNode processBody(Object cdr) { + if (cdr instanceof RPairList) { + RPairList pl = (RPairList) cdr; + switch (pl.getType()) { + case BCODESXP: + RAbstractListVector list = (RAbstractListVector) pl.cdr(); + return process(list.getDataAtAsObject(0), false); + case LISTSXP: + assert pl.cdr() == RNull.instance || (pl.cadr() == RNull.instance && pl.cddr() == RNull.instance); + return process(pl.car(), false); + case LANGSXP: + return processCall(pl.car(), pl.cdr(), pl.getTag()); + default: + throw RInternalError.shouldNotReachHere("unexpected SXP type in body: " + pl.getType()); + } + } + return process(cdr, false); + } + } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java index 330f46c849ec03ab2e440a41f1ca7cba95e70e8c..2e867d308647cce6bfdb76a499c4e95261cfeb45 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java @@ -22,8 +22,6 @@ */ package com.oracle.truffle.r.runtime.context; -import java.util.Map; - import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.RootCallTarget; @@ -119,11 +117,9 @@ public interface Engine { /** * Parse an R expression and return an {@link RExpression} object representing the Truffle ASTs - * for the components. The {Code constants} map can be used to replace some names in the source - * code with specific constants, which can be used to parse code that has no proper textual - * representation. + * for the components. */ - RExpression parse(Map<String, Object> constants, Source source) throws ParseException; + RExpression parse(Source source) throws ParseException; /** * This is the external interface from {@link PolyglotEngine#eval(Source)}. It is required to @@ -198,10 +194,4 @@ public interface Engine { * Essentially this is equivalent to {@link #evalFunction} using the {@code "print"} function. */ void printResult(Object value); - - /** - * This function a special fast path to create functions from code directly, without executing - * the intermediate "function" expression. - */ - RFunction parseFunction(Map<String, Object> constants, String name, Source source, MaterializedFrame enclosingFrame) throws ParseException; } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java index 4530068e0a7e9e532dc892b7799500e9b2751c78..3ecd606d1a5dabd63307d6cc5a666185a29b4fcb 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java @@ -467,8 +467,8 @@ public final class RDataFactory { return traceDataCreated(new RPairList(car, cdr, tag, type)); } - public static RFunction createFunction(String name, RootCallTarget target, RBuiltinDescriptor builtin, MaterializedFrame enclosingFrame) { - return traceDataCreated(new RFunction(name, target, builtin, enclosingFrame)); + public static RFunction createFunction(String name, String packageName, RootCallTarget target, RBuiltinDescriptor builtin, MaterializedFrame enclosingFrame) { + return traceDataCreated(new RFunction(name, packageName, target, builtin, enclosingFrame)); } private static final AtomicInteger environmentCount = new AtomicInteger(); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFunction.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFunction.java index 0ec52202d4806b9cf83be65955d91a1cdf35efd3..5dbc653ad82849d749f0803464e5527a3ec2be95 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFunction.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFunction.java @@ -48,13 +48,15 @@ public final class RFunction extends RSharingAttributeStorage implements RTypedV public static final String NO_NAME = new String(""); - private String name; + private final String name; + private final String packageName; private final RootCallTarget target; private final RBuiltinDescriptor builtin; private final MaterializedFrame enclosingFrame; - RFunction(String name, RootCallTarget target, RBuiltinDescriptor builtin, MaterializedFrame enclosingFrame) { + RFunction(String name, String packageName, RootCallTarget target, RBuiltinDescriptor builtin, MaterializedFrame enclosingFrame) { + this.packageName = packageName; this.target = target; this.builtin = builtin; this.name = name; @@ -82,6 +84,10 @@ public final class RFunction extends RSharingAttributeStorage implements RTypedV return name; } + public String getPackageName() { + return packageName; + } + public RootCallTarget getTarget() { return target; } @@ -108,7 +114,7 @@ public final class RFunction extends RSharingAttributeStorage implements RTypedV @Override public RFunction copy() { - RFunction newFunction = RDataFactory.createFunction(getName(), getTarget(), getRBuiltin(), getEnclosingFrame()); + RFunction newFunction = RDataFactory.createFunction(getName(), getPackageName(), getTarget(), getRBuiltin(), getEnclosingFrame()); if (getAttributes() != null) { RAttributes newAttributes = newFunction.initAttributes(); for (RAttribute attr : getAttributes()) { @@ -119,5 +125,4 @@ public final class RFunction extends RSharingAttributeStorage implements RTypedV newFunction.setTypedValueInfo(getTypedValueInfo()); return newFunction; } - } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RSyntaxElement.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RSyntaxElement.java index 685eb5f0975e71f2cf5aa99f82dcee122977c009..a97299f2bab84533cbd3f1f3db9979a277c99df5 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RSyntaxElement.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RSyntaxElement.java @@ -37,7 +37,7 @@ public interface RSyntaxElement { /** * This is a special version of {@link #getSourceSection} that does not try to - * {@link RDeparse#ensureSourceSection(RSyntaxElement) deparse} {@link SourceSection}s that are + * {@link RDeparse#ensureSourceSection(RSyntaxNode) deparse} {@link SourceSection}s that are * {@link RSyntaxNode#INTERNAL internal}. */ SourceSection getLazySourceSection(); 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 90532417fa2f6d21fff917b1418f3ad7190a026b..770ebe2b4ec977c8fd227b52fcf946edeb8a4417 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 @@ -9540,7 +9540,7 @@ In bitwShiftL(c(1, 2, 3, 4), c("a")) : NAs introduced by coercion #{ bitwShiftL(c(25,57,66), c(10,20,30,40,50,60)) } [1] 25600 59768832 NA NA NA NA -##com.oracle.truffle.r.test.builtins.TestBuiltin_bitwiseShiftL.testBitwiseFunctions#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.builtins.TestBuiltin_bitwiseShiftL.testBitwiseFunctions# #{ bitwShiftL(c(3+3i), c(3,2,4)) } Error in bitwShiftL(c(3 + (0+3i)), c(3, 2, 4)) : unimplemented type 'complex' in 'bitShiftL' @@ -15844,11 +15844,11 @@ Error in print(x, y) : #deparse(quote(cat(-17))) [1] "cat(-17)" -##com.oracle.truffle.r.test.builtins.TestBuiltin_deparse.testDeparse#Ignored.OutputFormatting# +##com.oracle.truffle.r.test.builtins.TestBuiltin_deparse.testDeparse# #deparse(quote(cat(-199.1234-5i))) [1] "cat(-199.1234 - (0+5i))" -##com.oracle.truffle.r.test.builtins.TestBuiltin_deparse.testDeparse#Ignored.OutputFormatting# +##com.oracle.truffle.r.test.builtins.TestBuiltin_deparse.testDeparse# #deparse(quote(cat(-5i))) [1] "cat(-(0+5i))" @@ -15920,7 +15920,7 @@ Error in print(x, y) : #deparse(quote(cat(17))) [1] "cat(17)" -##com.oracle.truffle.r.test.builtins.TestBuiltin_deparse.testDeparse#Ignored.OutputFormatting# +##com.oracle.truffle.r.test.builtins.TestBuiltin_deparse.testDeparse# #deparse(quote(cat(199.1234-5i))) [1] "cat(199.1234 - (0+5i))" @@ -17227,7 +17227,7 @@ $foo #{ digamma(1) } [1] -0.5772157 -##com.oracle.truffle.r.test.builtins.TestBuiltin_digamma.testDiGamma#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.builtins.TestBuiltin_digamma.testDiGamma# #{ digamma(1+1i) } Error in digamma(1 + (0+1i)) : unimplemented complex function @@ -17444,7 +17444,7 @@ Error in dim(x) <- integer() : length-0 dimension vector is invalid #{ x<-1:12; dim(x)<-c(12); x } [1] 1 2 3 4 5 6 7 8 9 10 11 12 -##com.oracle.truffle.r.test.builtins.TestBuiltin_dim.testDimensions#Output.IgnoreWarningContext# +##com.oracle.truffle.r.test.builtins.TestBuiltin_dim.testDimensions# #{ x<-1:12; dim(x)<-c(12+10i); x } [1] 1 2 3 4 5 6 7 8 9 10 11 12 Warning message: @@ -24924,7 +24924,7 @@ FALSE FALSE #argv <- list(structure(list(Topic = c('myTst-package', 'foo-class', 'myTst', 'show,foo-method', 'show,foo-method', 'show-methods'), File = c('myTst-package', 'foo-class', 'myTst-package', 'foo-class', 'show-methods', 'show-methods')), .Names = c('Topic', 'File'), row.names = c(3L, 1L, 4L, 2L, 6L, 5L), class = 'data.frame'));is.matrix(argv[[1]]); [1] FALSE -##com.oracle.truffle.r.test.builtins.TestBuiltin_isna.testIsNA#Ignored.Unimplemented# +##com.oracle.truffle.r.test.builtins.TestBuiltin_isna.testIsNA# #is.na(data.frame(col1=1:5, col2=c(NA, 1, NA, 2, NA))) col1 col2 [1,] FALSE TRUE @@ -25040,7 +25040,7 @@ FALSE [445] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE [457] FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE -##com.oracle.truffle.r.test.builtins.TestBuiltin_isna.testisna13#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestBuiltin_isna.testisna13# #argv <- list(structure(list(VAR1 = c(1, 2, 3, 4, 5), VAR3 = c(1, 1, 1, 1, NA)), .Names = c('VAR1', 'VAR3'), class = 'data.frame', row.names = c(NA, -5L)));is.na(argv[[1]]); VAR1 VAR3 [1,] FALSE FALSE @@ -25409,7 +25409,7 @@ logical(0) #argv <- list(complex(real = 3, imaginary = -Inf));do.call('is.null', argv) [1] FALSE -##com.oracle.truffle.r.test.builtins.TestBuiltin_isnull.testisnull16#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestBuiltin_isnull.testisnull16# #argv <- list(function(file = ifelse(onefile, 'Rplots.pdf', 'Rplot%03d.pdf'), width, height, onefile, family, title, fonts, version, paper, encoding, bg, fg, pointsize, pagecentre, colormodel, useDingbats, useKerning, fillOddEven, compress) { invisible() });do.call('is.null', argv) [1] FALSE @@ -26849,7 +26849,7 @@ Error in lengths(quote(a)) : 'x' must be a list or atomic vector #{ x <- 1 ; levels(x)<-4.5; levels(x);} [1] 4.5 -##com.oracle.truffle.r.test.builtins.TestBuiltin_levels.testLevels# +##com.oracle.truffle.r.test.builtins.TestBuiltin_levels.testLevels#Output.IgnoreErrorContext# #{ x <- 1 ; levels(x)<-NULL; levels(notx)} Error in levels(notx) : object 'notx' not found @@ -27244,7 +27244,7 @@ Levels: age1824 age2534 age3544 age4554 age5564 age6599 #{ lgamma(1) } [1] 0 -##com.oracle.truffle.r.test.builtins.TestBuiltin_lgamma.testLgamma#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.builtins.TestBuiltin_lgamma.testLgamma# #{ lgamma(1+1i) } Error in lgamma(1 + (0+1i)) : unimplemented complex function @@ -30949,7 +30949,7 @@ In max() : no non-missing arguments to max; returning -Inf #{ max(2L, 4L) } [1] 4 -##com.oracle.truffle.r.test.builtins.TestBuiltin_max.testMaximum#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.builtins.TestBuiltin_max.testMaximum# #{ max(42+42i, 7+7i) } Error in max(42 + (0+42i), 7 + (0+7i)) : invalid 'type' (complex) of argument @@ -31644,7 +31644,7 @@ In min() : no non-missing arguments to min; returning Inf #{ min(2L, 4L) } [1] 2 -##com.oracle.truffle.r.test.builtins.TestBuiltin_min.testMinimum#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.builtins.TestBuiltin_min.testMinimum# #{ min(42+42i, 7+7i) } Error in min(42 + (0+42i), 7 + (0+7i)) : invalid 'type' (complex) of argument @@ -39789,7 +39789,7 @@ V 0.0cwt 0.2cwt 0.4cwt 0.6cwt #argv <- list(NULL, NULL, TRUE, NULL, NULL, FALSE, NULL, TRUE, TRUE); .Internal(print.default(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]], argv[[8]], argv[[9]])) NULL -##com.oracle.truffle.r.test.builtins.TestBuiltin_printdefault.testprintdefault18#Ignored.OutputFormatting# +##com.oracle.truffle.r.test.builtins.TestBuiltin_printdefault.testprintdefault18# #argv <- list(quote(breaks ~ (wool + tension) - tension), NULL, TRUE, NULL, NULL, FALSE, NULL, TRUE, TRUE); .Internal(print.default(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]], argv[[8]], argv[[9]])) breaks ~ (wool + tension) - tension @@ -44823,14 +44823,14 @@ Error in seq.int(argv[[1]], argv[[2]], argv[[3]]) : [1] 58 0a 00 00 00 02 00 03 03 02 00 02 03 00 00 00 00 10 00 00 00 01 00 04 00 [26] 09 00 00 00 03 62 61 7a -##com.oracle.truffle.r.test.builtins.TestBuiltin_serialize.testserialize#Ignored.ImplementationError# +##com.oracle.truffle.r.test.builtins.TestBuiltin_serialize.testserialize# #options(keep.source=FALSE); serialize(quote((a %asdf% b)), connection=NULL) [1] 58 0a 00 00 00 02 00 03 03 02 00 02 03 00 00 00 00 06 00 00 00 01 00 04 00 [26] 09 00 00 00 01 28 00 00 00 02 00 00 00 06 00 00 00 01 00 04 00 09 00 00 00 [51] 06 25 61 73 64 66 25 00 00 00 02 00 00 00 01 00 04 00 09 00 00 00 01 61 00 [76] 00 00 02 00 00 00 01 00 04 00 09 00 00 00 01 62 00 00 00 fe 00 00 00 fe -##com.oracle.truffle.r.test.builtins.TestBuiltin_serialize.testserialize#Ignored.ImplementationError# +##com.oracle.truffle.r.test.builtins.TestBuiltin_serialize.testserialize# #options(keep.source=FALSE); serialize(quote((a+b)), connection=NULL) [1] 58 0a 00 00 00 02 00 03 03 02 00 02 03 00 00 00 00 06 00 00 00 01 00 04 00 [26] 09 00 00 00 01 28 00 00 00 02 00 00 00 06 00 00 00 01 00 04 00 09 00 00 00 @@ -44939,7 +44939,7 @@ Error in seq.int(argv[[1]], argv[[2]], argv[[3]]) : [76] 00 10 00 00 00 01 00 04 00 09 00 00 00 03 66 6f 6f 00 00 00 02 00 00 00 01 [101] 00 04 00 09 00 00 00 01 78 00 00 00 fe 00 00 00 02 00 00 00 fe 00 00 00 fe -##com.oracle.truffle.r.test.builtins.TestBuiltin_serialize.testserialize#Ignored.ImplementationError# +##com.oracle.truffle.r.test.builtins.TestBuiltin_serialize.testserialize# #options(keep.source=FALSE); serialize(quote(function(x) { `+`(`(`("BAR"), x) }), connection=NULL) [1] 58 0a 00 00 00 02 00 03 03 02 00 02 03 00 00 00 00 06 00 00 00 01 00 04 00 [26] 09 00 00 00 08 66 75 6e 63 74 69 6f 6e 00 00 00 02 00 00 04 02 00 00 00 01 @@ -45717,7 +45717,7 @@ Error in signif(42.1234, "2") : #{ signif(42.1234, 1:2) } [1] 40 42 -##com.oracle.truffle.r.test.builtins.TestBuiltin_signif.testSignif#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.builtins.TestBuiltin_signif.testSignif# #{ signif(42.1234, 42+7i) } Error in signif(42.1234, 42 + (0+7i)) : non-numeric argument to mathematical function @@ -53853,10 +53853,263 @@ Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1 [1] 123 [1] 123 -##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testserializeAndUnserializeClosure#Ignored.OutputFormatting# +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testserializeAndUnserializeClosure#Output.IgnoreWhitespace# #unserialize(serialize(function (x) { x }, NULL)) function (x) { x } +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote("bar"), connection=NULL)) +[1] "bar" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote('asdf'), connection=NULL)) +[1] "asdf" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote('baz'), connection=NULL)) +[1] "baz" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote((a %asdf% b)), connection=NULL)) +(a %asdf% b) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote((a+b)), connection=NULL)) +(a + b) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote(111+11), connection=NULL)) +111 + 11 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote(111+8i), connection=NULL)) +111 + (0+8i) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote(111L), connection=NULL)) +[1] 111 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote(FALSE), connection=NULL)) +[1] FALSE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote(NA_character_ + NA_complex_ + NA_integer_ + NA_real_), connection=NULL)) +NA_character_ + (NA_complex_) + NA_integer_ + NA_real_ + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote(NA_character_), connection=NULL)) +[1] NA + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote(NA_complex_), connection=NULL)) +[1] NA + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote(NA_integer_), connection=NULL)) +[1] NA + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote(NA_real_), connection=NULL)) +[1] NA + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote(TRUE), connection=NULL)) +[1] TRUE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize#Output.IgnoreWhitespace# +#options(keep.source=FALSE); unserialize(serialize(quote(a(b(c(d(function (e, ...) { f(g)$h.i}))))), connection=NULL)) +a(b(c(d(function(e, ...) { + f(g)$h.i +})))) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote(a+b), connection=NULL)) +a + b + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote(f(g)$h.i), connection=NULL)) +f(g)$h.i + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote(foo(a,b,c)), connection=NULL)) +foo(a, b, c) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize#Output.IgnoreWhitespace# +#options(keep.source=FALSE); unserialize(serialize(quote(function() new("foo", x)), connection=NULL)) +function() new("foo", x) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote(function(x) { `+`(`(`("BAR"), x) }), connection=NULL)) +function(x) { + ("BAR") + x +} + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize#Output.IgnoreWhitespace# +#options(keep.source=FALSE); unserialize(serialize(quote(function(x) { new("BAR", x) }), connection=NULL)) +function(x) { + new("BAR", x) +} + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize#Output.IgnoreWhitespace# +#options(keep.source=FALSE); unserialize(serialize(quote(function(x, ...) { new("BAR", x) }), connection=NULL)) +function(x, ...) { + new("BAR", x) +} + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize#Output.IgnoreWhitespace# +#options(keep.source=FALSE); unserialize(serialize(quote(function(x,y) { TRUE }), connection=NULL)) +function(x, y) { + TRUE +} + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize#Output.IgnoreWhitespace# +#options(keep.source=FALSE); unserialize(serialize(quote(function(x,y) { new("BAR", x) }), connection=NULL)) +function(x, y) { + new("BAR", x) +} + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize#Output.IgnoreWhitespace# +#options(keep.source=FALSE); unserialize(serialize(quote(function(x,y,...) { 1 }), connection=NULL)) +function(x, y, ...) { + 1 +} + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize#Output.IgnoreWhitespace# +#options(keep.source=FALSE); unserialize(serialize(quote(function(x,y=1,...) { NA }), connection=NULL)) +function(x, y = 1, ...) { + NA +} + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize#Ignored.OutputFormatting# +#options(keep.source=FALSE); unserialize(serialize(quote(function(x={1 + a},y,...) { !!NA }), connection=NULL)) +function(x = { + 1 + a +}, y, ...) { + !(!NA) +} + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote(function(x={1 + a},y,...) { !1+5i }), connection=NULL)) +function(x = { + 1 + a +}, y, ...) { + !1 + (0+5i) +} + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote(function(x={1 + a},y,...) { NA }), connection=NULL)) +function(x = { + 1 + a +}, y, ...) { + NA +} + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote(function(x={1 + a},y=c(1,2,3),z="foo",...) { !1+5i }), connection=NULL)) +function(x = { + 1 + a +}, y = c(1, 2, 3), z = "foo", ...) { + !1 + (0+5i) +} + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote(if (a * 2 < 199) b + foo(x,y,foo=z+1,bar=)), connection=NULL)) +if (a * 2 < 199) b + foo(x, y, foo = z + 1, bar = ) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote(if (a) b else c), connection=NULL)) +if (a) b else c + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote(if (a) {b} else {c}), connection=NULL)) +if (a) { + b +} else { + c +} + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote(if ({a}) {b} else {c}), connection=NULL)) +if ({ + a +}) { + b +} else { + c +} + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize#Output.IgnoreWhitespace# +#options(keep.source=FALSE); unserialize(serialize(quote(repeat {b; if (c) next else break}), connection=NULL)) +repeat { + b + if (c) + next + else break +} + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote(while (a) b), connection=NULL)) +while (a) b + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote(x), connection=NULL)) +x + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); unserialize(serialize(quote({ foo(a,b,c) }), connection=NULL)) +{ + foo(a, b, c) +} + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#options(keep.source=FALSE); val <- defaultPrototype(); unserialize(serialize(val, connection=NULL)) +<S4 Type Object> + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize#Output.ContainsReferences# +#options(keep.source=FALSE); val <- list(enclos = new.env(hash=FALSE)); unserialize(serialize(val, connection=NULL)) +$enclos +<environment: 0x7fa93ab11ab0> + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize#Output.ContainsReferences# +#options(keep.source=FALSE); val <- new.env(hash=FALSE); unserialize(serialize(val, connection=NULL)) +<environment: 0x7fc0c88c78a8> + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize#Output.ContainsReferences# +#options(keep.source=FALSE); val <- new.env(hash=FALSE); val$a <- 'foo'; unserialize(serialize(val, connection=NULL)) +<environment: 0x7fc5914a1ad8> + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize#Output.ContainsReferences# +#options(keep.source=FALSE); val <- new.env(hash=FALSE); val$b <- 123; unserialize(serialize(val, connection=NULL)) +<environment: 0x7fe9532eb830> + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize#Output.ContainsReferences# +#options(keep.source=FALSE); val <- new.env(hash=FALSE); val$c <- 1233L; unserialize(serialize(val, connection=NULL)) +<environment: 0x7ff64a5862d8> + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize#Output.ContainsReferences# +#options(keep.source=FALSE); val <- new.env(hash=FALSE); val$d <- TRUE; unserialize(serialize(val, connection=NULL)) +<environment: 0x7fcac6388ad8> + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize#Output.ContainsReferences# +#options(keep.source=FALSE); val <- new.env(hash=FALSE); val$e <- 5+9i; unserialize(serialize(val, connection=NULL)) +<environment: 0x7f80c3679d50> + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize#Output.ContainsReferences# +#options(keep.source=FALSE); val <- new.env(hash=FALSE); val$f <- NA; unserialize(serialize(val, connection=NULL)) +<environment: 0x7fa9028d50d8> + +##com.oracle.truffle.r.test.builtins.TestBuiltin_unserialize.testunserialize# +#setClass('foo', slots = c(x='numeric', y='numeric')); t1 <- new('foo', x=4, y=c(77,88)); options(keep.source=FALSE); unserialize(serialize(t1, connection=NULL)) +An object of class "foo" +Slot "x": +[1] 4 + +Slot "y": +[1] 77 88 + + ##com.oracle.truffle.r.test.builtins.TestBuiltin_utf8ToInt.testutf8ToInt1#Ignored.Unknown# #argv <- list('lasy'); .Internal(utf8ToInt(argv[[1]])) [1] 108 97 115 121 @@ -55696,7 +55949,7 @@ $x #{ f <- function() { stop("hello","world") } ; f() } Error in f() : helloworld -##com.oracle.truffle.r.test.builtins.TestMiscBuiltins.testEigen#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestMiscBuiltins.testEigen# #{ eigen(10, only.values=FALSE) } $values [1] 10 @@ -55706,17 +55959,17 @@ $vectors [1,] 1 -##com.oracle.truffle.r.test.builtins.TestMiscBuiltins.testEigen#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestMiscBuiltins.testEigen# #{ r <- eigen(matrix(c(1,2,2,3), nrow=2), only.values=FALSE); round( r$values, digits=5 ) } [1] 4.23607 -0.23607 -##com.oracle.truffle.r.test.builtins.TestMiscBuiltins.testEigen#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestMiscBuiltins.testEigen# #{ r <- eigen(matrix(c(1,2,2,3), nrow=2), only.values=FALSE); round( r$vectors, digits=5 ) } [,1] [,2] [1,] 0.52573 -0.85065 [2,] 0.85065 0.52573 -##com.oracle.truffle.r.test.builtins.TestMiscBuiltins.testEigen#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestMiscBuiltins.testEigen# #{ r <- eigen(matrix(c(1,2,3,4), nrow=2), only.values=FALSE); round( r$values, digits=5 ) } [1] 5.37228 -0.37228 @@ -55726,21 +55979,21 @@ $vectors [1,] -0.56577 -0.90938 [2,] -0.82456 0.41597 -##com.oracle.truffle.r.test.builtins.TestMiscBuiltins.testEigen#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestMiscBuiltins.testEigen# #{ r <- eigen(matrix(c(3,-2,4,-1), nrow=2), only.values=FALSE); round( r$values, digits=5 ) } [1] 1+2i 1-2i -##com.oracle.truffle.r.test.builtins.TestMiscBuiltins.testEigen#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestMiscBuiltins.testEigen# #{ r <- eigen(matrix(c(3,-2,4,-1), nrow=2), only.values=FALSE); round( r$vectors, digits=5 ) } [,1] [,2] [1,] 0.81650+0.00000i 0.81650+0.00000i [2,] -0.40825+0.40825i -0.40825-0.40825i -##com.oracle.truffle.r.test.builtins.TestMiscBuiltins.testEigen#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestMiscBuiltins.testEigen# #{ r <- eigen(matrix(rep(1,4), nrow=2), only.values=FALSE) ; round( r$values, digits=5 ) } [1] 2 0 -##com.oracle.truffle.r.test.builtins.TestMiscBuiltins.testEigen#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestMiscBuiltins.testEigen# #{ r <- eigen(matrix(rep(1,4), nrow=2), only.values=FALSE) ; round( r$vectors, digits=5 ) } [,1] [,2] [1,] 0.70711 -0.70711 @@ -56114,7 +56367,7 @@ Levels: Control Treat #{ sub <- function(x,y) { x - y }; sub(10,5) } [1] 5 -##com.oracle.truffle.r.test.builtins.TestMiscBuiltins.testParen#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestMiscBuiltins.testParen# #{ a = array(1,c(3,3,3)); (a[1,2,3] = 3) } [1] 3 @@ -63442,7 +63695,7 @@ $dimnames[[3]] -##com.oracle.truffle.r.test.library.base.TestSimpleAttributes.testBuiltinPropagationIgnore#Ignored.Unknown# +##com.oracle.truffle.r.test.library.base.TestSimpleAttributes.testBuiltinPropagationIgnore# #{ m <- matrix(c(1,1,1,1), nrow=2) ; attr(m,"a") <- 1 ; r <- eigen(m) ; r$vectors <- round(r$vectors, digits=5) ; r } $values [1] 2 0 @@ -67789,7 +68042,7 @@ NULL #{ (0-5):(0-9) } [1] -5 -6 -7 -8 -9 -##com.oracle.truffle.r.test.library.base.TestSimpleSequences.testSequenceConstruction#Output.IgnoreWarningContext# +##com.oracle.truffle.r.test.library.base.TestSimpleSequences.testSequenceConstruction# #{ (1:3):(1:3) } [1] 1 Warning messages: @@ -67798,7 +68051,7 @@ Warning messages: 2: In (1:3):(1:3) : numerical expression has 3 elements: only the first used -##com.oracle.truffle.r.test.library.base.TestSimpleSequences.testSequenceConstruction#Output.IgnoreWarningContext# +##com.oracle.truffle.r.test.library.base.TestSimpleSequences.testSequenceConstruction# #{ (1:3):3 } [1] 1 2 3 Warning message: @@ -99435,23 +99688,23 @@ Error in x[[1 + (0+1i), 1]] <- c(7, 42) : #{ x<-c(1,2,3,4); dim(x)<-c(2,2); x[[1+1i, 1]]<-integer() } Error in x[[1 + (0+1i), 1]] <- integer() : replacement has length zero -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex# #{ x<-c(1,2,3,4); x[1+1i]<-NULL } Error in x[1 + (0+1i)] <- NULL : invalid subscript type 'complex' -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex# #{ x<-c(1,2,3,4); x[1+1i]<-c(1) } Error in x[1 + (0+1i)] <- c(1) : invalid subscript type 'complex' -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex# #{ x<-c(1,2,3,4); x[1+1i]<-c(1,2) } Error in x[1 + (0+1i)] <- c(1, 2) : invalid subscript type 'complex' -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex# #{ x<-c(1,2,3,4); x[1+1i]<-c(1,2,3) } Error in x[1 + (0+1i)] <- c(1, 2, 3) : invalid subscript type 'complex' -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex# #{ x<-c(1,2,3,4); x[1+1i]<-integer() } Error in x[1 + (0+1i)] <- integer() : invalid subscript type 'complex' @@ -99460,7 +99713,7 @@ Error in x[1 + (0+1i)] <- integer() : invalid subscript type 'complex' Error in x[[1 + (0+1i)]] <- NULL : more elements supplied than there are to replace -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex# #{ x<-c(1,2,3,4); x[[1+1i]]<-c(1) } Error in x[[1 + (0+1i)]] <- c(1) : invalid subscript type 'complex' @@ -99518,43 +99771,43 @@ Error in `[[<-`(`*tmp*`, 1 + (0+1i), 1, value = c(7, 42)) : Error in `[[<-`(`*tmp*`, 1 + (0+1i), 1, value = integer(0)) : invalid subscript type 'complex' -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex# #{ x<-list(1,2,3,4); x[1+1i]<-NULL } Error in x[1 + (0+1i)] <- NULL : invalid subscript type 'complex' -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex# #{ x<-list(1,2,3,4); x[1+1i]<-c(1) } Error in x[1 + (0+1i)] <- c(1) : invalid subscript type 'complex' -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex# #{ x<-list(1,2,3,4); x[1+1i]<-c(1,2) } Error in x[1 + (0+1i)] <- c(1, 2) : invalid subscript type 'complex' -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex# #{ x<-list(1,2,3,4); x[1+1i]<-c(1,2,3) } Error in x[1 + (0+1i)] <- c(1, 2, 3) : invalid subscript type 'complex' -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex# #{ x<-list(1,2,3,4); x[1+1i]<-integer() } Error in x[1 + (0+1i)] <- integer() : invalid subscript type 'complex' -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex# #{ x<-list(1,2,3,4); x[[1+1i]]<-NULL } Error in x[[1 + (0+1i)]] <- NULL : invalid subscript type 'complex' -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex# #{ x<-list(1,2,3,4); x[[1+1i]]<-c(1) } Error in x[[1 + (0+1i)]] <- c(1) : invalid subscript type 'complex' -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex# #{ x<-list(1,2,3,4); x[[1+1i]]<-c(1,2) } Error in x[[1 + (0+1i)]] <- c(1, 2) : invalid subscript type 'complex' -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex# #{ x<-list(1,2,3,4); x[[1+1i]]<-c(1,2,3) } Error in x[[1 + (0+1i)]] <- c(1, 2, 3) : invalid subscript type 'complex' -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testComplexIndex# #{ x<-list(1,2,3,4); x[[1+1i]]<-integer() } Error in x[[1 + (0+1i)]] <- integer() : invalid subscript type 'complex' @@ -102906,7 +103159,7 @@ Error in x[[NA]] <- NULL : #{ x<-1:2; dim(x)<-c(1,2); u<-2+2i; x[[u, u]] } Error in x[[u, u]] : invalid subscript type 'complex' -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testMoreVectorsOther#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testMoreVectorsOther# #{ x<-1:2; dim(x)<-c(1,2); x[2+2i, 2+2i] } Error in x[2 + (0+2i), 2 + (0+2i)] : invalid subscript type 'complex' @@ -103103,7 +103356,7 @@ Error in `[[<-`(`*tmp*`, c(0, 1, 1), value = c(42, 43)) : Error in x[[c(0, 42 + (0+7i))]] <- c(42, 43) : invalid subscript type 'complex' -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testMoreVectorsOther#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testMoreVectorsOther# #{ x<-1:4; dim(x)<-c(2,2); x[[c(1+1i)]]<-c(42); x } Error in x[[c(1 + (0+1i))]] <- c(42) : invalid subscript type 'complex' @@ -103262,16 +103515,16 @@ In x[c(0, 1)] <- c(42, 43) : [1,] 43 3 [2,] 2 4 -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testMoreVectorsOther#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testMoreVectorsOther# #{ x<-1:4; dim(x)<-c(2,2); x[c(0,42+7i)]<-c(42,43); x } Error in x[c(0, 42 + (0+7i))] <- c(42, 43) : invalid subscript type 'complex' -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testMoreVectorsOther#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testMoreVectorsOther# #{ x<-1:4; dim(x)<-c(2,2); x[c(1+1i)]<-c(42); x } Error in x[c(1 + (0+1i))] <- c(42) : invalid subscript type 'complex' -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testMoreVectorsOther#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testMoreVectorsOther# #{ x<-1:4; dim(x)<-c(2,2); x[c(1+1i)]<-c(42,43); x } Error in x[c(1 + (0+1i))] <- c(42, 43) : invalid subscript type 'complex' @@ -103279,7 +103532,7 @@ Error in x[c(1 + (0+1i))] <- c(42, 43) : invalid subscript type 'complex' #{ x<-1:4; dim(x)<-c(2,2); x[c(1+1i)]<-integer(); x } Error in x[c(1 + (0+1i))] <- integer() : invalid subscript type 'complex' -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testMoreVectorsOther#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testMoreVectorsOther# #{ x<-1:4; dim(x)<-c(2,2); x[c(1+1i,42+7i,3+3i)]<-c(42,43); x } Error in x[c(1 + (0+1i), 42 + (0+7i), 3 + (0+3i))] <- c(42, 43) : invalid subscript type 'complex' @@ -108502,7 +108755,7 @@ Error in x[[list(-0, -1)]] : #{ x <- 1:2; x[[list(0)]] } Error in x[[list(0)]] : invalid subscript type 'list' -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testVectorIndex#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testVectorIndex# #{ x <- 1:3; x[function(){3}] } Error in x[function() { : invalid subscript type 'closure' @@ -108667,7 +108920,7 @@ Error in x[[i]] : invalid subscript type 'complex' #{ x <- list(a=1,b=1:3) ; f <- function(i) { x[[i]] } ; f(c(2,2)) ; x <- f ; f(2+3i) } Error in x[[i]] : object of type 'closure' is not subsettable -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testVectorIndex#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testVectorIndex# #{ x <- list(a=1,b=1:3) ; x[[2+3i]] } Error in x[[2 + (0+3i)]] : invalid subscript type 'complex' @@ -108997,7 +109250,7 @@ Error in b[c(3, 2)] <- 2 : [1] 2 -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testVectorUpdate#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testVectorUpdate# #{ b <- as.raw(1:5) ; b[c(TRUE,FALSE,TRUE)] <- c(1+2i,3+4i) ; b } Error in b[c(TRUE, FALSE, TRUE)] <- c(1 + (0+2i), 3 + (0+4i)) : incompatible types (from complex to raw) in subassignment type fix @@ -109115,7 +109368,7 @@ Error in b[c(TRUE, FALSE, FALSE)] <- NULL : replacement has length zero [1] 1+2i -##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testVectorUpdate#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testVectorUpdate# #{ b <- c(1,2,5) ; b[c(TRUE,NA,TRUE)] <- list(TRUE,1+2i) ; b } Error in b[c(TRUE, NA, TRUE)] <- list(TRUE, 1 + (0+2i)) : NAs are not allowed in subscripted assignments diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_args.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_args.java index ede905ba639f426d618613cca8cc3c0713dbd661..1303d70f84ad911190805a46d15c50e00067ebc2 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_args.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_args.java @@ -47,6 +47,6 @@ public class TestBuiltin_args extends TestBase { assertEval("{ f <- function(a) {}; fa <- args(f); }"); assertEval("{ f <- function(a, b) {}; fa <- args(f); }"); assertEval("{ sa <- args(sum); }"); - assertEval("{ f <- function(x=1, y) x + y; args(f); }"); + assertEval(Output.IgnoreWhitespace, "{ f <- function(x=1, y) x + y; args(f); }"); } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asfunction.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asfunction.java index b0432a40b7d1b1a86be53c5f91686a31760b0bb6..95b6ce40cdbe5442990d31fa483f141e632c6951 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asfunction.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asfunction.java @@ -30,8 +30,8 @@ public class TestBuiltin_asfunction extends TestBase { @Test public void testasfunction() { - assertEval("as.function(c(alist(a=1+14, b=foo(x),c=), quote(a+foo(c)*b)))"); - assertEval("f <- function() a+foo(c)*b; as.function(c(alist(a=1+14, b=foo(x),c=), body(f)))"); + assertEval(Output.IgnoreWhitespace, "as.function(c(alist(a=1+14, b=foo(x),c=), quote(a+foo(c)*b)))"); + assertEval(Output.IgnoreWhitespace, "f <- function() a+foo(c)*b; as.function(c(alist(a=1+14, b=foo(x),c=), body(f)))"); assertEval("foo <- function(x) x*2; as.function(c(alist(a=1+14, b=foo(x),c=), quote(a+foo(c)*b)))(c=3,b=1)"); assertEval("foo <- function(x) x*2; f <- function() a+foo(c)*b; as.function(c(alist(a=1+14, b=foo(x),c=), body(f)))(c=3,b=1)"); assertEval("{ as.function(alist(42))() }"); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_bitwiseShiftL.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_bitwiseShiftL.java index 6e33441b3be4ea000c0c32de930a6a988bd4e62e..480abb29840f7e8e24970ebbfd98e7724e7fcb35 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_bitwiseShiftL.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_bitwiseShiftL.java @@ -31,8 +31,7 @@ public class TestBuiltin_bitwiseShiftL extends TestBase { assertEval("{ bitwShiftL(TRUE, c(TRUE, FALSE)) }"); - // Error message mismatch - assertEval(Output.IgnoreErrorContext, "{ bitwShiftL(c(3+3i), c(3,2,4)) }"); + assertEval("{ bitwShiftL(c(3+3i), c(3,2,4)) }"); // Warning message mismatch assertEval(Output.IgnoreWarningContext, "{ bitwShiftL(c(3,2,4), c(3+3i)) }"); // No warning message printed for NAs produced by coercion diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_deparse.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_deparse.java index f1581fdeebbebcd9780417bd66467ff65e4c88be..071f3a353962ee7d1205b4a095f5ffb4358ca974 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_deparse.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_deparse.java @@ -270,7 +270,7 @@ public class TestBuiltin_deparse extends TestBase { assertEval("argv <- list(quote(x[[i]] <- 0.9999997), 500L, TRUE, 69, -1L); .Internal(deparse(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]]))"); } - private static final String[] VALUES = new String[]{"TRUE", "c(T, F)", "17", "-17", "0L", "-0L", "16L", "-16L", "5i", "NA_integer_", "NA_complex_", + private static final String[] VALUES = new String[]{"TRUE", "c(T, F)", "17", "-17", "0L", "-0L", "16L", "-16L", "5i", "-5i", "199.1234-5i", "-199.1234-5i", "NA_integer_", "NA_complex_", "NA_real_", "NA_character_", "1:2", "1:6", "0", "1", "1000", "10000", "99999", "100000000", "10000000000000", "0.1", "0.123", "0.00123", "0.0000000001", "0.0000000000000001", "1.545234523452345252523452345", "Inf", "NaN", "-0", "-1", "-1000", "-10000", "-99999", "-100000000", "-10000000000000", "-0.1", "-0.123", "-0.00123", "-0.0000000001", "-0.0000000000000001", "-1.545234523452345252523452345", "-Inf", "c(1L,2L,3L)", "c(1,2,3)", "c(NA_integer_, 1L,2L,3L)", "c(1L,2L,3L, NA_integer_)", "c(3L,2L,1L)", @@ -280,12 +280,6 @@ public class TestBuiltin_deparse extends TestBase { public void testDeparse() { assertEval(template("deparse(%0)", VALUES)); assertEval(template("deparse(quote(cat(%0)))", VALUES)); - assertEval("deparse(-5i)"); - assertEval(Ignored.OutputFormatting, "deparse(quote(cat(-5i)))"); - assertEval("deparse(199.1234-5i)"); - assertEval(Ignored.OutputFormatting, "deparse(quote(cat(199.1234-5i)))"); - assertEval("deparse(-199.1234-5i)"); - assertEval(Ignored.OutputFormatting, "deparse(quote(cat(-199.1234-5i)))"); assertEval(Ignored.OutputFormatting, "deparse(1.53160350210786e-322)"); assertEval("{ deparse(new.env()) }"); assertEval("{ k <- 2 ; deparse(k) }"); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_digamma.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_digamma.java index c2556e91b4df924ed458f2775f265dc1ec42ada5..143dd8f317cca17573338c33f40569b878bf633f 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_digamma.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_digamma.java @@ -53,6 +53,6 @@ public class TestBuiltin_digamma extends TestBase { assertEval("{ digamma(c(100, 2.2)) }"); assertEval("{ digamma(FALSE) }"); assertEval("{ digamma(as.raw(1)) }"); - assertEval(Output.IgnoreErrorContext, "{ digamma(1+1i) }"); + assertEval("{ digamma(1+1i) }"); } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dim.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dim.java index b18378be4564e68d04ecec2de73f7837443fbcb7..d527dec5c882e06a46ffca647ed8d79738ee21ae 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dim.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dim.java @@ -186,7 +186,7 @@ public class TestBuiltin_dim extends TestBase { assertEval("{ x <- 1:4 ; f <- function() { x <- 1:4 ; dim(x) <<- c(2,2) } ; f() ; dim(x) }"); assertEval("{ x<-1:12; dim(x)<-c(12); x }"); - assertEval(Output.IgnoreWarningContext, "{ x<-1:12; dim(x)<-c(12+10i); x }"); + assertEval("{ x<-1:12; dim(x)<-c(12+10i); x }"); assertEval("{ x<-1:12; dim(x)<-c(as.raw(12)); x }"); assertEval("{ x<-1:12; dim(x)<-c(\"12\"); x }"); assertEval("{ x<-1:1; dim(x)<-c(TRUE); x }"); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_lgamma.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_lgamma.java index 7cfe89a93f219a3551ecbd1db603a875de67aa65..30e927da8e3e374a2d622d882f1c950fce785be6 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_lgamma.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_lgamma.java @@ -68,6 +68,6 @@ public class TestBuiltin_lgamma extends TestBase { assertEval("{ lgamma(c(100, 2.2)) }"); assertEval("{ lgamma(FALSE) }"); assertEval("{ lgamma(as.raw(1)) }"); - assertEval(Output.IgnoreErrorContext, "{ lgamma(1+1i) }"); + assertEval("{ lgamma(1+1i) }"); } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_max.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_max.java index c2389ce4841980d8c774e2251f32ce9cc25b1a74..9988eac042eb0b431b23b0e8d09dd63d67b35ebc 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_max.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_max.java @@ -180,7 +180,7 @@ public class TestBuiltin_max extends TestBase { assertEval("{ is.logical(max(TRUE, FALSE)) }"); assertEval("{ is.logical(max(TRUE)) }"); assertEval("{ max(as.raw(42), as.raw(7)) }"); - assertEval(Output.IgnoreErrorContext, "{ max(42+42i, 7+7i) }"); + assertEval("{ max(42+42i, 7+7i) }"); assertEval("{ max(\"42\", \"7\") }"); assertEval("{ max(as.double(NA), na.rm=FALSE) }"); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_min.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_min.java index beca4afa68c9c66c08c810f15394cc894ace305c..8cf0b4359dd248d93f856ad87479d6cdd89a5f2c 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_min.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_min.java @@ -148,7 +148,7 @@ public class TestBuiltin_min extends TestBase { assertEval("{ is.logical(min(TRUE, FALSE)) }"); assertEval("{ is.logical(min(TRUE)) }"); assertEval("{ min(as.raw(42), as.raw(7)) }"); - assertEval(Output.IgnoreErrorContext, "{ min(42+42i, 7+7i) }"); + assertEval("{ min(42+42i, 7+7i) }"); assertEval("{ min(\"42\", \"7\") }"); assertEval("{ min(as.double(NA), na.rm=FALSE) }"); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_signif.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_signif.java index de5976c0fd0aab29a2d541fae97574869857b9de..8d4de54a5b60042f9730f26db65bbdc902f13d56 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_signif.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_signif.java @@ -34,7 +34,7 @@ public class TestBuiltin_signif extends TestBase { assertEval("{ signif(42.1234, \"2\") }"); assertEval("{ signif(42.1234, as.raw(2)) }"); - assertEval(Output.IgnoreErrorContext, "{ signif(42.1234, 42+7i) }"); + assertEval("{ signif(42.1234, 42+7i) }"); assertEval(Output.IgnoreErrorMessage, "{ signif(42.1234, character()) }"); assertEval("{ signif(\"42.1234\", 2 }"); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_unserialize.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_unserialize.java index ffe49c08587df723136734fbfc576bf594b48925..786a26fcd95d42e49bde626fbff43eb454c63004 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_unserialize.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_unserialize.java @@ -41,7 +41,64 @@ public class TestBuiltin_unserialize extends TestBase { @Test public void testserializeAndUnserializeClosure() { // N.B.: FastR does not preserve code formatting like GNU R does - assertEval(Ignored.OutputFormatting, "unserialize(serialize(function (x) { x }, NULL))"); + assertEval(Output.IgnoreWhitespace, "unserialize(serialize(function (x) { x }, NULL))"); assertEval("f <- function() x; e <- new.env(); e$x <- 123; environment(f) <- e; expr <- substitute({ FUN() }, list(FUN=f)); eval(expr); expr <- unserialize(serialize(expr, NULL)); eval(expr)"); } + + @Test + public void testunserialize() { + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(x), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(TRUE), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(FALSE), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote('asdf'), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(NA_character_), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(NA_complex_), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(NA_integer_), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(NA_real_), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(NA_character_ + NA_complex_ + NA_integer_ + NA_real_), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(111L), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(111+8i), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(111+11), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(a+b), connection=NULL))"); + + assertEval("options(keep.source=FALSE); unserialize(serialize(quote((a+b)), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote((a %asdf% b)), connection=NULL))"); + + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(foo(a,b,c)), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote({ foo(a,b,c) }), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(if (a) b else c), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(if (a) {b} else {c}), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(if ({a}) {b} else {c}), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(while (a) b), connection=NULL))"); + assertEval(Output.IgnoreWhitespace, "options(keep.source=FALSE); unserialize(serialize(quote(repeat {b; if (c) next else break}), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(if (a * 2 < 199) b + foo(x,y,foo=z+1,bar=)), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(\"bar\"), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote('baz'), connection=NULL))"); + assertEval("setClass('foo', slots = c(x='numeric', y='numeric')); t1 <- new('foo', x=4, y=c(77,88)); options(keep.source=FALSE); unserialize(serialize(t1, connection=NULL))"); + assertEval(Output.IgnoreWhitespace, "options(keep.source=FALSE); unserialize(serialize(quote(a(b(c(d(function (e, ...) { f(g)$h.i}))))), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(f(g)$h.i), connection=NULL))"); + assertEval(Output.ContainsReferences, "options(keep.source=FALSE); val <- new.env(hash=FALSE); unserialize(serialize(val, connection=NULL))"); + assertEval(Output.ContainsReferences, "options(keep.source=FALSE); val <- list(enclos = new.env(hash=FALSE)); unserialize(serialize(val, connection=NULL))"); + assertEval("options(keep.source=FALSE); val <- defaultPrototype(); unserialize(serialize(val, connection=NULL))"); + assertEval(Output.IgnoreWhitespace, "options(keep.source=FALSE); unserialize(serialize(quote(function() new(\"foo\", x)), connection=NULL))"); + assertEval(Output.IgnoreWhitespace, "options(keep.source=FALSE); unserialize(serialize(quote(function(x) { new(\"BAR\", x) }), connection=NULL))"); + assertEval(Output.IgnoreWhitespace, "options(keep.source=FALSE); unserialize(serialize(quote(function(x, ...) { new(\"BAR\", x) }), connection=NULL))"); + assertEval(Output.IgnoreWhitespace, "options(keep.source=FALSE); unserialize(serialize(quote(function(x,y) { new(\"BAR\", x) }), connection=NULL))"); + assertEval(Output.IgnoreWhitespace, "options(keep.source=FALSE); unserialize(serialize(quote(function(x,y) { TRUE }), connection=NULL))"); + assertEval(Output.IgnoreWhitespace, "options(keep.source=FALSE); unserialize(serialize(quote(function(x,y,...) { 1 }), connection=NULL))"); + assertEval(Output.IgnoreWhitespace, "options(keep.source=FALSE); unserialize(serialize(quote(function(x,y=1,...) { NA }), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(function(x={1 + a},y,...) { NA }), connection=NULL))"); + assertEval(Ignored.OutputFormatting, "options(keep.source=FALSE); unserialize(serialize(quote(function(x={1 + a},y,...) { !!NA }), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(function(x={1 + a},y,...) { !1+5i }), connection=NULL))"); + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(function(x={1 + a},y=c(1,2,3),z=\"foo\",...) { !1+5i }), connection=NULL))"); + + assertEval("options(keep.source=FALSE); unserialize(serialize(quote(function(x) { `+`(`(`(\"BAR\"), x) }), connection=NULL))"); + + assertEval(Output.ContainsReferences, "options(keep.source=FALSE); val <- new.env(hash=FALSE); val$a <- 'foo'; unserialize(serialize(val, connection=NULL))"); + assertEval(Output.ContainsReferences, "options(keep.source=FALSE); val <- new.env(hash=FALSE); val$b <- 123; unserialize(serialize(val, connection=NULL))"); + assertEval(Output.ContainsReferences, "options(keep.source=FALSE); val <- new.env(hash=FALSE); val$c <- 1233L; unserialize(serialize(val, connection=NULL))"); + assertEval(Output.ContainsReferences, "options(keep.source=FALSE); val <- new.env(hash=FALSE); val$d <- TRUE; unserialize(serialize(val, connection=NULL))"); + assertEval(Output.ContainsReferences, "options(keep.source=FALSE); val <- new.env(hash=FALSE); val$e <- 5+9i; unserialize(serialize(val, connection=NULL))"); + assertEval(Output.ContainsReferences, "options(keep.source=FALSE); val <- new.env(hash=FALSE); val$f <- NA; unserialize(serialize(val, connection=NULL))"); + } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleSequences.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleSequences.java index 5687355087d7e0e3e406d54f609c68827d8cecae..dc4f1bdb0eade007de69ea3e2e28451cddeddc05 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleSequences.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleSequences.java @@ -50,12 +50,9 @@ public class TestSimpleSequences extends TestBase { assertEval("{ 10:1 }"); assertEval("{ (0-5):(0-9) }"); assertEval("{ 1.1:5.1 }"); - assertEval("{ 1:(1:3) }"); - - // these two test need proper handling of parentheses - assertEval(Output.IgnoreWarningContext, "{ (1:3):3 }"); - assertEval(Output.IgnoreWarningContext, "{ (1:3):(1:3) }"); + assertEval("{ (1:3):3 }"); + assertEval("{ (1:3):(1:3) }"); } @Test diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleVectors.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleVectors.java index 7157061c65bb50848ff325e62e19759cddaea321..8d13bc5d5bb3ab54da393bd64f8f88332cf0d2d0 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleVectors.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleVectors.java @@ -284,7 +284,7 @@ public class TestSimpleVectors extends TestBase { assertEval(Output.IgnoreErrorContext, "{ x<-c(1,2); x[[c(\"a\", \"b\")]] }"); assertEval("{ x<-1:2; x[c(TRUE, TRUE)] }"); assertEval(Output.IgnoreErrorContext, "{ x<-1:2; x[[c(TRUE, TRUE)]] }"); - assertEval(Output.IgnoreErrorContext, "{ x<-1:2; dim(x)<-c(1,2); x[2+2i, 2+2i] }"); + assertEval("{ x<-1:2; dim(x)<-c(1,2); x[2+2i, 2+2i] }"); assertEval("{ x<-1:2; dim(x)<-c(1,2); u<-2+2i; x[[u, u]] }"); assertEval("{ x<-2; x[NULL] }"); assertEval(Output.IgnoreErrorContext, "{ x<-2; x[[NULL]] }"); @@ -428,16 +428,16 @@ public class TestSimpleVectors extends TestBase { assertEval(Output.IgnoreErrorContext, "{ x<-1:4; dim(x)<-c(2,2); x[[c(FALSE,TRUE,TRUE)]]<-c(42,43); x }"); assertEval(Output.IgnoreErrorMessage, "{ x<-1:4; dim(x)<-c(2,2); x[[complex()]]<-c(42,43); x }"); assertEval(Output.IgnoreErrorMessage, "{ x<-1:4; dim(x)<-c(2,2); x[[c(1+1i)]]<-integer(); x }"); - assertEval(Output.IgnoreErrorContext, "{ x<-1:4; dim(x)<-c(2,2); x[[c(1+1i)]]<-c(42); x }"); + assertEval("{ x<-1:4; dim(x)<-c(2,2); x[[c(1+1i)]]<-c(42); x }"); assertEval(Output.IgnoreErrorMessage, "{ x<-1:4; dim(x)<-c(2,2); x[[c(1+1i)]]<-c(42,43); x }"); assertEval(Output.IgnoreErrorMessage, "{ x<-1:4; dim(x)<-c(2,2); x[[c(1+1i,42+7i,3+3i)]]<-c(42,43); x }"); assertEval(Output.IgnoreErrorMessage, "{ x<-1:4; dim(x)<-c(2,2); x[[c(0,42+7i)]]<-c(42,43); x }"); assertEval(Output.IgnoreErrorMessage, "{ x<-1:4; dim(x)<-c(2,2); x[c(1+1i)]<-integer(); x }"); - assertEval(Output.IgnoreErrorContext, "{ x<-1:4; dim(x)<-c(2,2); x[c(1+1i)]<-c(42); x }"); + assertEval("{ x<-1:4; dim(x)<-c(2,2); x[c(1+1i)]<-c(42); x }"); assertEval("{ x<-1:4; dim(x)<-c(2,2); x[complex()]<-c(42,43); x }"); - assertEval(Output.IgnoreErrorContext, "{ x<-1:4; dim(x)<-c(2,2); x[c(1+1i)]<-c(42,43); x }"); - assertEval(Output.IgnoreErrorContext, "{ x<-1:4; dim(x)<-c(2,2); x[c(1+1i,42+7i,3+3i)]<-c(42,43); x }"); - assertEval(Output.IgnoreErrorContext, "{ x<-1:4; dim(x)<-c(2,2); x[c(0,42+7i)]<-c(42,43); x }"); + assertEval("{ x<-1:4; dim(x)<-c(2,2); x[c(1+1i)]<-c(42,43); x }"); + assertEval("{ x<-1:4; dim(x)<-c(2,2); x[c(1+1i,42+7i,3+3i)]<-c(42,43); x }"); + assertEval("{ x<-1:4; dim(x)<-c(2,2); x[c(0,42+7i)]<-c(42,43); x }"); assertEval(Output.IgnoreErrorContext, "{ x<-1:4; dim(x)<-c(2,2); x[[c(0,0,42+71)]]<-c(42,43); x }"); assertEval(Output.IgnoreErrorMessage, "{ x<-1:4; dim(x)<-c(2,2); x[[c(as.raw(integer()))]]<-c(42,43); x }"); assertEval(Output.IgnoreErrorMessage, "{ x<-1:4; dim(x)<-c(2,2); x[[c(as.raw(42))]]<-integer(); x }"); @@ -771,14 +771,14 @@ public class TestSimpleVectors extends TestBase { @Test public void testComplexIndex() { assertEval(Output.IgnoreErrorMessage, "{ x<-c(1,2,3,4); x[[1+1i]]<-integer() }"); - assertEval(Output.IgnoreErrorContext, "{ x<-c(1,2,3,4); x[[1+1i]]<-c(1) }"); + assertEval("{ x<-c(1,2,3,4); x[[1+1i]]<-c(1) }"); assertEval(Output.IgnoreErrorMessage, "{ x<-c(1,2,3,4); x[[1+1i]]<-c(1,2) }"); assertEval(Output.IgnoreErrorMessage, "{ x<-c(1,2,3,4); x[[1+1i]]<-c(1,2,3) }"); - assertEval(Output.IgnoreErrorContext, "{ x<-c(1,2,3,4); x[1+1i]<-NULL }"); - assertEval(Output.IgnoreErrorContext, "{ x<-c(1,2,3,4); x[1+1i]<-integer() }"); - assertEval(Output.IgnoreErrorContext, "{ x<-c(1,2,3,4); x[1+1i]<-c(1) }"); - assertEval(Output.IgnoreErrorContext, "{ x<-c(1,2,3,4); x[1+1i]<-c(1,2) }"); - assertEval(Output.IgnoreErrorContext, "{ x<-c(1,2,3,4); x[1+1i]<-c(1,2,3) }"); + assertEval("{ x<-c(1,2,3,4); x[1+1i]<-NULL }"); + assertEval("{ x<-c(1,2,3,4); x[1+1i]<-integer() }"); + assertEval("{ x<-c(1,2,3,4); x[1+1i]<-c(1) }"); + assertEval("{ x<-c(1,2,3,4); x[1+1i]<-c(1,2) }"); + assertEval("{ x<-c(1,2,3,4); x[1+1i]<-c(1,2,3) }"); assertEval(Output.IgnoreErrorMessage, "{ x<-c(1,2,3,4); dim(x)<-c(2,2); x[[1+1i, 1]]<-integer() }"); assertEval(Output.IgnoreErrorContext, "{ x<-c(1,2,3,4); dim(x)<-c(2,2); x[[1+1i, 1]]<-7 }"); @@ -787,16 +787,16 @@ public class TestSimpleVectors extends TestBase { assertEval(Output.IgnoreErrorContext, "{ x<-c(1,2,3,4); dim(x)<-c(2,2); x[1+1i, 1]<-7 }"); assertEval(Output.IgnoreErrorContext, "{ x<-c(1,2,3,4); dim(x)<-c(2,2); x[1+1i, 1]<-c(7,42) }"); - assertEval(Output.IgnoreErrorContext, "{ x<-list(1,2,3,4); x[[1+1i]]<-NULL }"); - assertEval(Output.IgnoreErrorContext, "{ x<-list(1,2,3,4); x[[1+1i]]<-integer() }"); - assertEval(Output.IgnoreErrorContext, "{ x<-list(1,2,3,4); x[[1+1i]]<-c(1) }"); - assertEval(Output.IgnoreErrorContext, "{ x<-list(1,2,3,4); x[[1+1i]]<-c(1,2) }"); - assertEval(Output.IgnoreErrorContext, "{ x<-list(1,2,3,4); x[[1+1i]]<-c(1,2,3) }"); - assertEval(Output.IgnoreErrorContext, "{ x<-list(1,2,3,4); x[1+1i]<-NULL }"); - assertEval(Output.IgnoreErrorContext, "{ x<-list(1,2,3,4); x[1+1i]<-integer() }"); - assertEval(Output.IgnoreErrorContext, "{ x<-list(1,2,3,4); x[1+1i]<-c(1) }"); - assertEval(Output.IgnoreErrorContext, "{ x<-list(1,2,3,4); x[1+1i]<-c(1,2) }"); - assertEval(Output.IgnoreErrorContext, "{ x<-list(1,2,3,4); x[1+1i]<-c(1,2,3) }"); + assertEval("{ x<-list(1,2,3,4); x[[1+1i]]<-NULL }"); + assertEval("{ x<-list(1,2,3,4); x[[1+1i]]<-integer() }"); + assertEval("{ x<-list(1,2,3,4); x[[1+1i]]<-c(1) }"); + assertEval("{ x<-list(1,2,3,4); x[[1+1i]]<-c(1,2) }"); + assertEval("{ x<-list(1,2,3,4); x[[1+1i]]<-c(1,2,3) }"); + assertEval("{ x<-list(1,2,3,4); x[1+1i]<-NULL }"); + assertEval("{ x<-list(1,2,3,4); x[1+1i]<-integer() }"); + assertEval("{ x<-list(1,2,3,4); x[1+1i]<-c(1) }"); + assertEval("{ x<-list(1,2,3,4); x[1+1i]<-c(1,2) }"); + assertEval("{ x<-list(1,2,3,4); x[1+1i]<-c(1,2,3) }"); assertEval(Output.IgnoreErrorMessage, "{ x<-list(1,2,3,4); dim(x)<-c(2,2); x[[1+1i, 1]]<-NULL }"); assertEval(Output.IgnoreErrorContext, "{ x<-list(1,2,3,4); dim(x)<-c(2,2); x[[1+1i, 1]]<-integer() }"); @@ -1352,10 +1352,10 @@ public class TestSimpleVectors extends TestBase { assertEval(Output.IgnoreErrorContext, "{ x <- c(a=1,b=2) ; x[[c(\"a\",\"a\")]] }"); assertEval("{ x <- list(1,2) ; x[[c(\"a\",\"a\")]] }"); assertEval("{ x <- list(a=1,b=1:3) ; x[[c(\"b\",\"a\")]] }"); - assertEval(Output.IgnoreErrorContext, "{ x <- list(a=1,b=1:3) ; x[[2+3i]] }"); + assertEval("{ x <- list(a=1,b=1:3) ; x[[2+3i]] }"); assertEval("{ x <- list(a=1,b=1:3) ; f <- function(i) { x[[i]] } ; f(c(2,2)) ; f(2+3i) }"); assertEval("{ x <- 1:3; x[list(2,3)] }"); - assertEval(Output.IgnoreErrorContext, "{ x <- 1:3; x[function(){3}] }"); + assertEval("{ x <- 1:3; x[function(){3}] }"); assertEval(Output.IgnoreErrorMessage, "{ x <- 1:2; x[[list()]] }"); assertEval(Output.IgnoreErrorMessage, "{ x <- 1:2; x[[list(-0,-1)]] }"); assertEval("{ x <- 1:2; x[[list(0)]] }"); @@ -1748,7 +1748,7 @@ public class TestSimpleVectors extends TestBase { assertEval("{ b <- c(1,2,5) ; b[c(TRUE,FALSE,FALSE)] <- NULL ; b }"); assertEval("{ b <- c(1,2,5) ; b[logical()] <- NULL ; b }"); - assertEval(Output.IgnoreErrorContext, "{ b <- c(1,2,5) ; b[c(TRUE,NA,TRUE)] <- list(TRUE,1+2i) ; b }"); + assertEval("{ b <- c(1,2,5) ; b[c(TRUE,NA,TRUE)] <- list(TRUE,1+2i) ; b }"); assertEval("{ b <- c(1,2,5) ; b[c(TRUE,FALSE,TRUE)] <- list(TRUE,1+2i) ; b }"); assertEval("{ b <- list(1,2,5) ; dim(b) <- c(1,3) ; b[c(TRUE,FALSE,TRUE)] <- list(TRUE,1+2i) ; b }"); assertEval("{ f <- function(b, i, v) { b[i] <- v ; b } ; f(1:3,c(TRUE,FALSE,TRUE),5:6) ; x <- list(1,2,5) ; dim(x) <- c(1,3) ; f(x, c(FALSE,TRUE,TRUE), list(TRUE,1+2i)) }"); @@ -1848,7 +1848,7 @@ public class TestSimpleVectors extends TestBase { assertEval("{ f <- function(b,i,v) { b[i] <- v ; b } ; f(c(\"a\",\"b\",\"c\"),c(TRUE,FALSE),c(\"A\",\"X\")) ; f(1:3,c(TRUE,FALSE),4) }"); assertEval("{ f <- function(b,i,v) { b[i] <- v ; b } ; f(c(\"a\",\"b\",\"c\"),c(TRUE,FALSE),c(\"A\",\"X\")) ; f(c(\"A\",\"X\"),c(TRUE,FALSE),4) }"); assertEval("{ b <- c(\"a\",\"b\",\"c\") ; b[c(TRUE,FALSE,TRUE)] <- c(1+2i,3+4i) ; b }"); - assertEval(Output.IgnoreErrorContext, "{ b <- as.raw(1:5) ; b[c(TRUE,FALSE,TRUE)] <- c(1+2i,3+4i) ; b }"); + assertEval("{ b <- as.raw(1:5) ; b[c(TRUE,FALSE,TRUE)] <- c(1+2i,3+4i) ; b }"); assertEval("{ f <- function(b,i,v) { b[i] <- v ; b } ; f(c(\"a\",\"b\",\"c\"),c(TRUE,FALSE),c(\"A\",\"X\")) ; f(f,c(TRUE,FALSE),4) }"); assertEval("{ f <- function(b,i,v) { b[i] <- v ; b } ; f(c(\"a\",\"b\",\"c\"),c(TRUE,FALSE),c(\"A\",\"X\")) ; f(c(\"A\",\"X\"),c(TRUE,FALSE),f) }");