Skip to content
Snippets Groups Projects
Commit 5156b615 authored by Michael Haupt's avatar Michael Haupt
Browse files

merge

parents dad81e9d 05a05197
No related branches found
No related tags found
No related merge requests found
......@@ -193,7 +193,7 @@ public class EnvFunctions {
RFunction func = (RFunction) funcArg;
Frame enclosing = func.getEnclosingFrame();
REnvironment env = RArguments.getEnvironment(enclosing);
return env == null ? REnvironment.lexicalChain(enclosing.materialize()) : env;
return env == null ? REnvironment.createEnclosingEnvironments(enclosing.materialize()) : env;
} else {
// Not an error according to GnuR
return RNull.instance;
......
......@@ -74,9 +74,6 @@ public abstract class Internal extends RBuiltinNode {
// .Internal function is validated
CompilerDirectives.transferToInterpreterAndInvalidate();
// Replace the original call; we can't just use callNode as that will cause recursion!
if (symbol.getName().equals("paste")) {
System.console();
}
RCallNode internalCallNode = RCallNode.createInternalCall(frame, this.getParent().getSourceSection(), callNode, function, symbol);
this.getParent().replace(internalCallNode);
// evaluate the actual builtin this time, next time we won't get here!
......
......@@ -57,8 +57,7 @@ public abstract class Substitute extends RBuiltinNode {
protected Object doSubstitute(VirtualFrame frame, RPromise expr, @SuppressWarnings("unused") RMissing envMissing) {
controlVisibility();
// In the global environment, substitute behaves like quote
REnvironment env = REnvironment.checkNonFunctionFrame(frame);
if (env == REnvironment.globalEnv()) {
if (REnvironment.isGlobalEnvFrame(frame)) {
return checkQuote().execute(frame, expr);
}
// We have to examine all the names in the expression:
......@@ -80,9 +79,7 @@ public abstract class Substitute extends RBuiltinNode {
// N.B. In many cases it is ok to just return the value, which is what we do to
// allow progress on package loading
}
if (env == null) {
env = REnvironment.frameToEnvironment(frame.materialize());
}
REnvironment env = REnvironment.frameToEnvironment(frame.materialize());
Object val = env.get(name);
if (val == null) {
// not bound in env
......
......@@ -72,6 +72,10 @@ import com.oracle.truffle.r.runtime.envframe.*;
* "imports" environment. The parent of "package:base" is the empty environment, but the parent of
* "namespace:base" is the global environment.
*
* Whereas R types generally use value semantics environments do not; they have reference semantics.
* In particular in FastR, there is exactly one environment created for any package or function
* Truffle frame, allowing equality to be tested using {@code ==}.
*
* TODO retire the {@code Package}, {@code Namespace} and {@code Imports} classes as they are only
* used by the builtin packages, and will be completely redundant when they are loaded from
* serialized package meta-data as will happen in due course.
......@@ -144,19 +148,14 @@ public abstract class REnvironment implements RAttributable {
* Returns {@code true} iff {@code frame} is that associated with {@code env}.
*/
public static boolean isFrameForEnv(Frame frame, REnvironment env) {
Object id = env.frameAccess.id();
if (id == null) {
return false;
}
FrameSlot idSlot = frame.getFrameDescriptor().findFrameSlot(id);
if (idSlot == null) {
return false;
REnvironment frameEnv = RArguments.getEnvironment(frame);
if (frameEnv == env) {
return true;
}
try {
return frame.getObject(idSlot) == id;
} catch (FrameSlotTypeException fste) {
return false;
if (frameEnv == null) {
frameEnv = createEnclosingEnvironments(frame.materialize());
}
return frameEnv == env;
}
/**
......@@ -182,7 +181,7 @@ public abstract class REnvironment implements RAttributable {
/**
* Check whether the given frame is indeed the frame stored in the global environment.
*/
public static boolean isGlobalEnvFrame(MaterializedFrame frame) {
public static boolean isGlobalEnvFrame(Frame frame) {
return isFrameForEnv(frame, globalEnv);
}
......@@ -426,32 +425,15 @@ public abstract class REnvironment implements RAttributable {
return result;
}
/**
* Check if a frame corresponds to a function. If there is no function associated with the
* frame, then is it one of the package environments. Fortunately, we do not have to do a search
* as, in this case, the {@link REnvironment} value is also stored in the frame.
*
* @return ({code null) if this is a function frame, else the associated environment
*/
public static REnvironment checkNonFunctionFrame(Frame frame) {
RFunction callerFunc = RArguments.getFunction(frame);
if (callerFunc == null) {
REnvironment env = RArguments.getEnvironment(frame);
assert env != null;
return env;
} else {
return null;
}
}
/**
* Converts a {@link Frame} to an {@link REnvironment}, which necessarily requires the frame to
* be materialized.
*/
public static REnvironment frameToEnvironment(MaterializedFrame frame) {
REnvironment env = checkNonFunctionFrame(frame);
REnvironment env = RArguments.getEnvironment(frame);
if (env == null) {
env = lexicalChain(frame);
assert RArguments.getFunction(frame) != null;
env = createEnclosingEnvironments(frame);
}
return env;
}
......@@ -466,11 +448,11 @@ public abstract class REnvironment implements RAttributable {
* {@link MaterializedFrame}.
*/
@SlowPath
public static REnvironment lexicalChain(MaterializedFrame frame) {
REnvironment env = checkNonFunctionFrame(frame);
public static REnvironment createEnclosingEnvironments(MaterializedFrame frame) {
REnvironment env = RArguments.getEnvironment(frame);
if (env == null) {
// parent is the env of the enclosing frame
env = REnvironment.Function.create(lexicalChain(RArguments.getEnclosingFrame(frame)), frame);
env = REnvironment.Function.create(createEnclosingEnvironments(RArguments.getEnclosingFrame(frame)), frame);
}
return env;
}
......@@ -844,10 +826,15 @@ public abstract class REnvironment implements RAttributable {
private Function(REnvironment parent, MaterializedFrame frame) {
// function environments are not named
super(parent, UNNAMED, frame);
// Associate frame with the environment
RArguments.setEnvironment(frame, this);
}
private static Function create(REnvironment parent, MaterializedFrame frame) {
Function result = new Function(parent, frame);
Function result = (Function) RArguments.getEnvironment(frame);
if (result == null) {
result = new Function(parent, frame);
}
return result;
}
......
......@@ -35,14 +35,6 @@ import com.oracle.truffle.r.runtime.data.*;
* environment which never has an associated frame.
*/
public class REnvFrameAccess {
/**
* Return the unique id that identifies the associated environment in the frame, or {@code null}
* if none.
*/
public Object id() {
throw notImplemented("id");
}
/**
* Return the value of object named {@code name} or {@code null} if not found.
*/
......@@ -70,7 +62,7 @@ public class REnvFrameAccess {
/**
* Return the names in the environment that match {@code pattern}.
*
*
* @param allNames if {@code false} ignore names beginning with ".".
* @param pattern if not {@code null} only include names matching {@code pattern}.
*/
......
......@@ -38,13 +38,8 @@ import com.oracle.truffle.r.runtime.data.*;
public class REnvTruffleFrameAccess extends REnvFrameAccessBindingsAdapter {
private MaterializedFrame frame;
private Object id;
public REnvTruffleFrameAccess(VirtualFrame frame) {
this.id = new Object();
FrameDescriptor fd = frame.getFrameDescriptor();
FrameSlot idSlot = fd.addFrameSlot(id);
frame.setObject(idSlot, id);
this.frame = frame.materialize();
}
......@@ -132,11 +127,6 @@ public class REnvTruffleFrameAccess extends REnvFrameAccessBindingsAdapter {
return null;
}
@Override
public Object id() {
return id;
}
private static String[] getStringIdentifiers(FrameDescriptor fd) {
return fd.getIdentifiers().stream().filter(e -> (e instanceof String)).collect(Collectors.toSet()).toArray(RRuntime.STRING_ARRAY_SENTINEL);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment