Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 6c8f7dde8636
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 598ea899a2c1
Choose a head ref
  • 7 commits
  • 8 files changed
  • 1 contributor

Commits on Feb 17, 2015

  1. Copy the full SHA
    c3e77fc View commit details
  2. Copy the full SHA
    ea7f45c View commit details
  3. [Truffle] Do not save any kind of lexicalScope into a RubyModule.

    * We might need the lexicalParent though in some cases if it is an anonymous module.
    eregon committed Feb 17, 2015
    Copy the full SHA
    84ac23d View commit details
  4. Copy the full SHA
    541bc0b View commit details
  5. Copy the full SHA
    ad2ab66 View commit details
  6. Copy the full SHA
    2bce6c7 View commit details
  7. [Truffle] Let RubyModule.setConstant() handle special values like mod…

    …ules.
    
    * RubyModule.name is now null or full.
    * RubyModule.getName() is a "forgiving" method in that it always provide some name.
    * Check with RubyModule.hasName() if there is already a sensible name.
    eregon committed Feb 17, 2015
    Copy the full SHA
    598ea89 View commit details
5 changes: 0 additions & 5 deletions spec/truffle/tags/core/module/name_tags.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
fails:Module#name is nil for an anonymous module
fails:Module#name is nil when assigned to a constant in an anonymous module
fails:Module#name is nil for a nested module created with the module keyword
fails:Module#name is set when assigning to a constant
fails:Module#name is not modified when assigning to a new constant after it has been accessed
fails:Module#name is set with a conditional assignment to a nested constant
fails:Module#name is set with a conditional assignment to a constant
fails:Module#name preserves the encoding in which the class was defined
fails:Module#name is set when the anonymous outer module name is set
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.runtime.LexicalScope;

import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyModule;
@@ -23,14 +23,12 @@
public class WriteConstantNode extends RubyNode {

private final String name;
private final LexicalScope lexicalScope;
@Child private RubyNode module;
@Child private RubyNode rhs;

public WriteConstantNode(RubyContext context, SourceSection sourceSection, String name, LexicalScope lexicalScope, RubyNode module, RubyNode rhs) {
public WriteConstantNode(RubyContext context, SourceSection sourceSection, String name, RubyNode module, RubyNode rhs) {
super(context, sourceSection);
this.name = name;
this.lexicalScope = lexicalScope;
this.module = module;
this.rhs = rhs;
}
@@ -42,14 +40,6 @@ public Object execute(VirtualFrame frame) {
// Evaluate RHS first.
final Object rhsValue = rhs.execute(frame);

if (rhsValue instanceof RubyModule) {
final RubyModule setModule = (RubyModule) rhsValue;
if (setModule.getName() == null) {
setModule.setLexicalScope(lexicalScope);
setModule.setName(name);
}
}

final Object receiverObject = module.execute(frame);

if (!(receiverObject instanceof RubyModule)) {
Original file line number Diff line number Diff line change
@@ -2181,11 +2181,6 @@ public RubyString toS(VirtualFrame frame, Object self) {
notDesignedForCompilation();

String className = classNode.executeGetClass(self).getName();

if (className == null) {
className = "Class";
}

Object id = objectIDNode.executeObjectID(frame, self);
String hexID = toHexStringNode.executeToHexString(frame, id);

Original file line number Diff line number Diff line change
@@ -720,14 +720,6 @@ public void setConstant(RubyModule module, String name, Object object) {
throw new RaiseException(getContext().getCoreLibrary().nameError(String.format("wrong constant name %s", name), this));
}

if (object instanceof RubyModule) {
final RubyModule setModule = (RubyModule) object;
if (setModule.getName() == null) {
setModule.setLexicalScope(new LexicalScope(null, module));
setModule.setName(name);
}
}

module.setConstant(this, name, object);
}

@@ -991,23 +983,11 @@ public NameNode(NameNode prev) {
public Object name(RubyModule module) {
notDesignedForCompilation();

if (module.getName() == null) {
if (!module.hasName()) {
return getContext().getCoreLibrary().getNilObject();
}

final StringBuilder builder = new StringBuilder();

builder.append(module.getName());

LexicalScope lexicalScope = module.getLexicalScope();

while (lexicalScope != null && lexicalScope.getLiveModule() != getContext().getCoreLibrary().getObjectClass()) {
builder.insert(0, "::");
builder.insert(0, lexicalScope.getLiveModule().getName());
lexicalScope = lexicalScope.getParent();
}

return getContext().makeString(builder.toString());
return getContext().makeString(module.getName());
}
}

Original file line number Diff line number Diff line change
@@ -161,10 +161,10 @@ public CoreLibrary(RubyContext context) {
moduleClass.unsafeSetSuperclass(objectClass);
classClass.unsafeSetSuperclass(moduleClass);

classClass.getAdoptedByLexicalParent(objectClass, null);
basicObjectClass.getAdoptedByLexicalParent(objectClass, null);
objectClass.getAdoptedByLexicalParent(objectClass, null);
moduleClass.getAdoptedByLexicalParent(objectClass, null);
classClass.getAdoptedByLexicalParent(objectClass, "Class", null);
basicObjectClass.getAdoptedByLexicalParent(objectClass, "BasicObject", null);
objectClass.getAdoptedByLexicalParent(objectClass, "Object", null);
moduleClass.getAdoptedByLexicalParent(objectClass, "Module", null);

// BasicObject knows itself

Original file line number Diff line number Diff line change
@@ -31,6 +31,7 @@
import org.jruby.truffle.runtime.subsystems.ObjectSpaceManager;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
* Represents the Ruby {@code Module} class.
@@ -88,12 +89,12 @@ public static void debugModuleChain(RubyModule module) {
private final RubyContext context;

@CompilationFinal protected ModuleChain parentModule;
private LexicalScope lexicalScope;

private String name;

private final Map<String, InternalMethod> methods = new HashMap<>();
private final Map<String, RubyConstant> constants = new HashMap<>();
private final Map<String, Object> classVariables = new HashMap<>();
private final Map<String, InternalMethod> methods = new ConcurrentHashMap<>();
private final Map<String, RubyConstant> constants = new ConcurrentHashMap<>();
private final Map<String, Object> classVariables = new ConcurrentHashMap<>();

private final CyclicAssumption unmodifiedAssumption;

@@ -114,31 +115,34 @@ public RubyModule(RubyContext context, RubyModule lexicalParent, String name, Ru
protected RubyModule(RubyContext context, RubyClass selfClass, RubyModule lexicalParent, String name, RubyNode currentNode) {
super(selfClass, context);
this.context = context;
this.name = name;

unmodifiedAssumption = new CyclicAssumption(name + " is unmodified");

getAdoptedByLexicalParent(lexicalParent, currentNode);
if (lexicalParent != null) {
getAdoptedByLexicalParent(lexicalParent, name, currentNode);
}
}

protected void getAdoptedByLexicalParent(RubyModule lexicalParent, RubyNode currentNode) {
if (lexicalParent != null) {
lexicalParent.setConstant(currentNode, name, this);
lexicalParent.addLexicalDependent(this);
public void getAdoptedByLexicalParent(RubyModule lexicalParent, String name, RubyNode currentNode) {
lexicalParent.setConstantInternal(currentNode, name, this);
lexicalParent.addLexicalDependent(this);

// Tricky, we need to compare with the Object class, but we only have a Module at hand.
RubyClass classClass = lexicalParent.getLogicalClass();
if (this.name == null) {
// Tricky, we need to compare with the Object class, but we only have a Class at hand.
RubyClass classClass = logicalClass.getLogicalClass();
RubyClass objectClass = classClass.getSuperClass().getSuperClass();

if (lexicalParent != objectClass) {
name = lexicalParent.getName() + "::" + name;
if (lexicalParent == objectClass) {
this.name = name;
} else if (lexicalParent.hasName()) {
this.name = lexicalParent.getName() + "::" + name;
}
}
}

@TruffleBoundary
public void initCopy(RubyModule other) {
this.name = other.name;
// Do not copy name, the copy is an anonymous module
this.parentModule = other.parentModule;
this.methods.putAll(other.methods);
this.constants.putAll(other.constants);
@@ -185,6 +189,14 @@ public void include(Node currentNode, RubyModule module) {
*/
@TruffleBoundary
public void setConstant(RubyNode currentNode, String name, Object value) {
if (value instanceof RubyModule) {
((RubyModule) value).getAdoptedByLexicalParent(this, name, currentNode);
} else {
setConstantInternal(currentNode, name, value);
}
}

private void setConstantInternal(RubyNode currentNode, String name, Object value) {
RubyNode.notDesignedForCompilation();

checkFrozen(currentNode);
@@ -316,7 +328,15 @@ public RubyContext getContext() {
}

public String getName() {
return name;
if (name != null) {
return name;
} else {
return "#<" + logicalClass.getName() + ":0x" + Long.toHexString(getObjectID()) + ">";
}
}

public boolean hasName() {
return name != null;
}

@Override
@@ -531,18 +551,6 @@ public Iterator<RubyModule> iterator() {
};
}

public void setName(String name) {
this.name = name;
}

public void setLexicalScope(LexicalScope lexicalScope) {
this.lexicalScope = lexicalScope;
}

public LexicalScope getLexicalScope() {
return lexicalScope;
}

public static class ModuleAllocator implements Allocator {

@Override
Original file line number Diff line number Diff line change
@@ -118,6 +118,8 @@ public void pauseAllThreadsAndExecuteFromNonRubyThread(Consumer<RubyThread> acti
}

private synchronized void pauseAllThreadsAndExecute(boolean holdsGlobalLock, Consumer<RubyThread> action) {
CompilerDirectives.transferToInterpreter();

this.action = action;

/* this is a potential cause for race conditions,
Original file line number Diff line number Diff line change
@@ -912,7 +912,7 @@ public RubyNode visitConstDeclNode(org.jruby.ast.ConstDeclNode node) {
throw new UnsupportedOperationException();
}

return new WriteConstantNode(context, sourceSection, node.getName(), environment.getLexicalScope(), moduleNode, node.getValueNode().accept(this));
return new WriteConstantNode(context, sourceSection, node.getName(), moduleNode, node.getValueNode().accept(this));
}

@Override