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: 93820f2083f3
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: c34c031763be
Choose a head ref
  • 18 commits
  • 48 files changed
  • 1 contributor

Commits on Oct 17, 2014

  1. [Truffle] Introduce LexicalScope to resolve constants.

    * Built during parsing, and completed with live modules when opening those.
    * No need for callingSelf except in the rare case of protected.
    * A few improvements on visbility checking.
    eregon committed Oct 17, 2014
    Copy the full SHA
    f25baf2 View commit details
  2. Copy the full SHA
    3b681af View commit details
  3. Copy the full SHA
    10be6ba View commit details
  4. Copy the full SHA
    5b6c7cf View commit details

Commits on Oct 20, 2014

  1. Copy the full SHA
    380de3b View commit details
  2. Copy the full SHA
    9640076 View commit details
  3. Copy the full SHA
    21d30da View commit details
  4. Copy the full SHA
    caf16a0 View commit details

Commits on Oct 21, 2014

  1. [Truffle] Fix Module#name.

    eregon committed Oct 21, 2014
    Copy the full SHA
    aa13f0c View commit details
  2. [Truffle] Fix most of constant lookup!

    * Use lexical scoping instead of pseudo-dynamic scoping.
    * Stop defining constants on singleton class, we define on the receiver only.
    * Temporarily disable the constant cache, we want better semantics first.
    eregon committed Oct 21, 2014
    Copy the full SHA
    286bee2 View commit details
  3. Copy the full SHA
    54be7dd View commit details
  4. Copy the full SHA
    002a256 View commit details
  5. Copy the full SHA
    f9292f3 View commit details
  6. Copy the full SHA
    5ccb89a View commit details
  7. Copy the full SHA
    4087b83 View commit details
  8. [Truffle] A few more specs in language/ are passing.

    * Also includes some fixes by the method lookup changes.
    eregon committed Oct 21, 2014
    Copy the full SHA
    9788867 View commit details
  9. [Truffle] Merge branch 'lexical_scope'

    * Constant cache is disabled for now.
    
    Conflicts:
    	core/src/main/java/org/jruby/truffle/nodes/core/CoreMethodNodeManager.java
    	core/src/main/java/org/jruby/truffle/runtime/RubyContext.java
    eregon committed Oct 21, 2014
    Copy the full SHA
    d673d88 View commit details
  10. Copy the full SHA
    c34c031 View commit details
Showing with 483 additions and 385 deletions.
  1. +20 −11 core/src/main/java/org/jruby/truffle/nodes/ReadConstantNode.java
  2. +2 −1 core/src/main/java/org/jruby/truffle/nodes/RubyCallNode.java
  3. +5 −0 core/src/main/java/org/jruby/truffle/nodes/RubyNode.java
  4. +2 −0 core/src/main/java/org/jruby/truffle/nodes/RubyTypes.java
  5. +12 −5 core/src/main/java/org/jruby/truffle/nodes/WriteConstantNode.java
  6. +2 −2 core/src/main/java/org/jruby/truffle/nodes/core/ArrayNodes.java
  7. +2 −2 core/src/main/java/org/jruby/truffle/nodes/core/CoreMethodNodeManager.java
  8. +1 −1 core/src/main/java/org/jruby/truffle/nodes/core/KernelNodes.java
  9. +19 −9 core/src/main/java/org/jruby/truffle/nodes/core/ModuleNodes.java
  10. +1 −1 core/src/main/java/org/jruby/truffle/nodes/core/SystemNode.java
  11. +6 −5 core/src/main/java/org/jruby/truffle/nodes/dispatch/CachedBooleanDispatchNode.java
  12. +6 −5 core/src/main/java/org/jruby/truffle/nodes/dispatch/CachedBoxedDispatchNode.java
  13. +6 −5 core/src/main/java/org/jruby/truffle/nodes/dispatch/CachedBoxedMethodMissingDispatchNode.java
  14. +6 −5 core/src/main/java/org/jruby/truffle/nodes/dispatch/CachedBoxedReturnMissingDispatchNode.java
  15. +5 −4 core/src/main/java/org/jruby/truffle/nodes/dispatch/CachedBoxedSymbolDispatchNode.java
  16. +2 −1 core/src/main/java/org/jruby/truffle/nodes/dispatch/CachedDispatchNode.java
  17. +7 −6 core/src/main/java/org/jruby/truffle/nodes/dispatch/CachedUnboxedDispatchNode.java
  18. +6 −6 core/src/main/java/org/jruby/truffle/nodes/dispatch/DispatchHeadNode.java
  19. +10 −23 core/src/main/java/org/jruby/truffle/nodes/dispatch/DispatchNode.java
  20. +19 −12 core/src/main/java/org/jruby/truffle/nodes/dispatch/GenericDispatchNode.java
  21. +52 −48 core/src/main/java/org/jruby/truffle/nodes/dispatch/UnresolvedDispatchNode.java
  22. +3 −0 core/src/main/java/org/jruby/truffle/nodes/methods/MethodDefinitionNode.java
  23. +8 −9 core/src/main/java/org/jruby/truffle/nodes/objects/DefineOrGetClassNode.java
  24. +8 −9 core/src/main/java/org/jruby/truffle/nodes/objects/DefineOrGetModuleNode.java
  25. +41 −0 core/src/main/java/org/jruby/truffle/nodes/objects/LexicalScopeNode.java
  26. +3 −0 core/src/main/java/org/jruby/truffle/nodes/objects/OpenModuleNode.java
  27. +2 −1 core/src/main/java/org/jruby/truffle/nodes/supercall/AbstractGeneralSuperCallNode.java
  28. +43 −0 core/src/main/java/org/jruby/truffle/runtime/LexicalScope.java
  29. +21 −14 core/src/main/java/org/jruby/truffle/runtime/ModuleOperations.java
  30. +22 −0 core/src/main/java/org/jruby/truffle/runtime/RubyContext.java
  31. +4 −0 core/src/main/java/org/jruby/truffle/runtime/core/CoreLibrary.java
  32. +1 −1 core/src/main/java/org/jruby/truffle/runtime/core/RubyBasicObject.java
  33. +1 −1 core/src/main/java/org/jruby/truffle/runtime/core/RubyClass.java
  34. +9 −54 core/src/main/java/org/jruby/truffle/runtime/core/RubyModule.java
  35. +1 −1 core/src/main/java/org/jruby/truffle/runtime/core/RubySymbol.java
  36. +4 −21 core/src/main/java/org/jruby/truffle/runtime/methods/RubyMethod.java
  37. +16 −1 core/src/main/java/org/jruby/truffle/runtime/methods/SharedMethodInfo.java
  38. +1 −1 core/src/main/java/org/jruby/truffle/runtime/subsystems/FeatureManager.java
  39. +97 −58 core/src/main/java/org/jruby/truffle/translator/BodyTranslator.java
  40. +1 −24 core/src/main/java/org/jruby/truffle/translator/ModuleTranslator.java
  41. +3 −4 core/src/main/java/org/jruby/truffle/translator/TranslatorDriver.java
  42. +0 −1 spec/truffle/tags/language/class_tags.txt
  43. +0 −20 spec/truffle/tags/language/constants_tags.txt
  44. +0 −4 spec/truffle/tags/language/defined_tags.txt
  45. +1 −5 spec/truffle/tags/language/metaclass_tags.txt
  46. +1 −0 spec/truffle/tags/language/module_tags.txt
  47. +0 −1 spec/truffle/tags/language/send_tags.txt
  48. +1 −3 spec/truffle/tags/language/singleton_class_tags.txt
31 changes: 20 additions & 11 deletions core/src/main/java/org/jruby/truffle/nodes/ReadConstantNode.java
Original file line number Diff line number Diff line change
@@ -12,44 +12,50 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.source.*;
import com.oracle.truffle.api.frame.*;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.jruby.truffle.nodes.*;
import org.jruby.truffle.nodes.cast.BoxingNode;
import org.jruby.truffle.nodes.dispatch.Dispatch;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNode;
import org.jruby.truffle.runtime.*;
import org.jruby.truffle.runtime.control.*;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyModule;
import org.jruby.truffle.runtime.methods.MethodLike;
import org.jruby.truffle.runtime.LexicalScope;

public class ReadConstantNode extends RubyNode {

private final boolean isLiteral;
private final String name;
@Child protected RubyNode receiver;
@Child protected DispatchHeadNode dispatch;

public ReadConstantNode(RubyContext context, SourceSection sourceSection, boolean isLiteral, String name, RubyNode receiver) {
public ReadConstantNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver) {
super(context, sourceSection);
this.isLiteral = isLiteral;
this.name = name;
this.receiver = receiver;
dispatch = new DispatchHeadNode(context, Dispatch.MissingBehavior.CALL_CONST_MISSING);
}

private LexicalScope getLexicalScope(VirtualFrame frame) {
MethodLike method = RubyArguments.getMethod(frame.getArguments());
if (method != null) {
return method.getSharedMethodInfo().getLexicalScope();
}
return null;
}

@Override
public Object execute(VirtualFrame frame) {
final Object receiverObject = receiver.execute(frame);

if (isLiteral && !(receiverObject instanceof RubyModule)) {
if (!(receiverObject instanceof RubyModule)) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().typeErrorIsNotA(receiverObject.toString(), "class/module", this));
}

LexicalScope lexicalScope = getLexicalScope(frame);

return dispatch.dispatch(
frame,
getContext().getCoreLibrary().getNilObject(),
RubyArguments.getSelf(frame.getArguments()),
lexicalScope,
receiverObject,
name,
null,
@@ -74,10 +80,10 @@ public Object isDefined(VirtualFrame frame) {
return context.makeString("constant");
}

Object value;
Object receiverObject;

try {
value = ModuleOperations.lookupConstant(context.getCoreLibrary().box(receiver.execute(frame)).getMetaClass(), name);
receiverObject = receiver.execute(frame);
} catch (RaiseException e) {
/*
* If we are looking up a constant in a constant that is itself undefined, we return Nil
@@ -91,6 +97,9 @@ public Object isDefined(VirtualFrame frame) {
throw e;
}

LexicalScope lexicalScope = getLexicalScope(frame);
Object value = ModuleOperations.lookupConstant(lexicalScope, (RubyModule) receiverObject, name);

if (value == null) {
return getContext().getCoreLibrary().getNilObject();
} else {
3 changes: 2 additions & 1 deletion core/src/main/java/org/jruby/truffle/nodes/RubyCallNode.java
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@
import org.jruby.truffle.runtime.core.RubyArray;
import org.jruby.truffle.runtime.methods.*;
import org.jruby.truffle.runtime.util.ArrayUtils;
import org.jruby.truffle.runtime.LexicalScope;

import java.util.Arrays;

@@ -204,7 +205,7 @@ public Object isDefined(VirtualFrame frame) {
}
} else if (method.isUndefined()) {
return getContext().getCoreLibrary().getNilObject();
} else if (!ignoreVisibility && !method.isVisibleTo(this, self)) {
} else if (!ignoreVisibility && !method.isVisibleTo(this, self.getMetaClass())) {
return getContext().getCoreLibrary().getNilObject();
}

5 changes: 5 additions & 0 deletions core/src/main/java/org/jruby/truffle/nodes/RubyNode.java
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.jruby.truffle.nodes.dispatch.Dispatch;
import org.jruby.truffle.nodes.yield.YieldDispatchNode;
import org.jruby.truffle.runtime.LexicalScope;
import org.jruby.truffle.runtime.RubyCallStack;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.UndefinedPlaceholder;
@@ -198,6 +199,10 @@ public Dispatch.DispatchAction executeDispatchAction(VirtualFrame frame) {
throw new UnsupportedOperationException();
}

public LexicalScope executeLexicalScope(VirtualFrame frame) {
throw new UnsupportedOperationException();
}

public void executeVoid(VirtualFrame frame) {
execute(frame);
}
2 changes: 2 additions & 0 deletions core/src/main/java/org/jruby/truffle/nodes/RubyTypes.java
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.rubinius.RubiniusByteArray;
import org.jruby.truffle.runtime.rubinius.RubiniusChannel;
import org.jruby.truffle.runtime.LexicalScope;

import java.math.BigInteger;

@@ -29,6 +30,7 @@
*/
@TypeSystem({ //
Dispatch.DispatchAction.class, //
LexicalScope.class, //
UndefinedPlaceholder.class, //
boolean.class, //
int.class, //
17 changes: 12 additions & 5 deletions core/src/main/java/org/jruby/truffle/nodes/WriteConstantNode.java
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@
import com.oracle.truffle.api.nodes.*;
import org.jruby.truffle.nodes.*;
import org.jruby.truffle.runtime.*;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.*;

/**
@@ -37,16 +38,22 @@ public WriteConstantNode(RubyContext context, SourceSection sourceSection, Strin
public Object execute(VirtualFrame frame) {
notDesignedForCompilation();

// TODO(cs): can module ever not evaluate to a RubyModule?

final RubyModule moduleObject = (RubyModule) module.execute(frame);

// Evaluate RHS first.
final Object rhsValue = rhs.execute(frame);

assert rhsValue != null;
assert !(rhsValue instanceof String);

moduleObject.setModuleConstant(this, name, rhsValue);
final Object receiverObject = module.execute(frame);

if (!(receiverObject instanceof RubyModule)) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().typeErrorIsNotA(receiverObject.toString(), "class/module", this));
}

final RubyModule module = (RubyModule) receiverObject;

module.setModuleConstant(this, name, rhsValue);

return rhsValue;
}
Original file line number Diff line number Diff line change
@@ -2320,7 +2320,7 @@ public MaxBlock(RubyContext context) {
frameDescriptor = new FrameDescriptor();
frameSlot = frameDescriptor.addFrameSlot("maximum_memo");

sharedMethodInfo = new SharedMethodInfo(sourceSection, "max", false, null);
sharedMethodInfo = SharedMethodInfo.generated(sourceSection, "max");

callTarget = Truffle.getRuntime().createCallTarget(new RubyRootNode(
context, sourceSection, null, sharedMethodInfo,
@@ -2433,7 +2433,7 @@ public MinBlock(RubyContext context) {
frameDescriptor = new FrameDescriptor();
frameSlot = frameDescriptor.addFrameSlot("minimum_memo");

sharedMethodInfo = new SharedMethodInfo(sourceSection, "min", false, null);
sharedMethodInfo = SharedMethodInfo.generated(sourceSection, "min");

callTarget = Truffle.getRuntime().createCallTarget(new RubyRootNode(
context, sourceSection, null, sharedMethodInfo,
Original file line number Diff line number Diff line change
@@ -64,7 +64,7 @@ private static void addMethod(RubyClass rubyObjectClass, MethodDetails methodDet
module = rubyObjectClass;

for (String moduleName : methodDetails.getClassAnnotation().name().split("::")) {
module = (RubyModule) ModuleOperations.lookupConstant(module, moduleName).getValue();
module = (RubyModule) ModuleOperations.lookupConstant(null, module, moduleName).getValue();
}
}

@@ -120,7 +120,7 @@ private static void addMethod(RubyModule module, RubyMethod method, List<String>
private static RubyRootNode makeGenericMethod(RubyContext context, MethodDetails methodDetails, boolean needsSelf) {
final CoreSourceSection sourceSection = new CoreSourceSection(methodDetails.getClassAnnotation().name(), methodDetails.getMethodAnnotation().names()[0]);

final SharedMethodInfo sharedMethodInfo = new SharedMethodInfo(sourceSection, methodDetails.getIndicativeName(), false, null);
final SharedMethodInfo sharedMethodInfo = SharedMethodInfo.generated(sourceSection, methodDetails.getIndicativeName());

final Arity arity = new Arity(methodDetails.getMethodAnnotation().minArgs(), methodDetails.getMethodAnnotation().maxArgs());

Original file line number Diff line number Diff line change
@@ -590,7 +590,7 @@ private static void exec(RubyContext context, String[] commandLine) {
final ProcessBuilder builder = new ProcessBuilder(commandLine);
builder.inheritIO();

final RubyHash env = (RubyHash) ModuleOperations.lookupConstant(context.getCoreLibrary().getObjectClass(), "ENV").getValue();
final RubyHash env = (RubyHash) ModuleOperations.lookupConstant(null, context.getCoreLibrary().getObjectClass(), "ENV").getValue();

// TODO(CS): cast
for (Map.Entry<Object, Object> entry : ((LinkedHashMap<Object, Object>) env.getStore()).entrySet()) {
28 changes: 19 additions & 9 deletions core/src/main/java/org/jruby/truffle/nodes/core/ModuleNodes.java
Original file line number Diff line number Diff line change
@@ -227,7 +227,7 @@ public static void attrReader(RubyNode currentNode, RubyContext context, SourceS

final String indicativeName = name + "(attr_reader)";

final SharedMethodInfo sharedMethodInfo = new SharedMethodInfo(sourceSection, indicativeName, false, null);
final SharedMethodInfo sharedMethodInfo = SharedMethodInfo.generated(sourceSection, indicativeName);
final RubyRootNode rootNode = new RubyRootNode(context, sourceSection, null, sharedMethodInfo, block);
final CallTarget callTarget = Truffle.getRuntime().createCallTarget(rootNode);
final RubyMethod method = new RubyMethod(sharedMethodInfo, name, module, Visibility.PUBLIC, false, callTarget, null);
@@ -280,7 +280,7 @@ public static void attrWriter(RubyNode currentNode, RubyContext context, SourceS

final String indicativeName = name + "(attr_writer)";

final SharedMethodInfo sharedMethodInfo = new SharedMethodInfo(sourceSection, indicativeName, false, null);
final SharedMethodInfo sharedMethodInfo = SharedMethodInfo.generated(sourceSection, indicativeName);
final RubyRootNode rootNode = new RubyRootNode(context, sourceSection, null, sharedMethodInfo, block);
final CallTarget callTarget = Truffle.getRuntime().createCallTarget(rootNode);
final RubyMethod method = new RubyMethod(sharedMethodInfo, name + "=", module, Visibility.PUBLIC, false, callTarget, null);
@@ -449,15 +449,15 @@ public ConstDefinedNode(ConstDefinedNode prev) {
public boolean isConstDefined(RubyModule module, RubyString name, @SuppressWarnings("unused") UndefinedPlaceholder inherit) {
notDesignedForCompilation();

return ModuleOperations.lookupConstant(module, name.toString()) != null;
return ModuleOperations.lookupConstant(null, module, name.toString()) != null;
}

@Specialization
public boolean isConstDefined(RubyModule module, RubyString name, boolean inherit) {
notDesignedForCompilation();

if (inherit) {
return ModuleOperations.lookupConstant(module, name.toString()) != null;
return ModuleOperations.lookupConstant(null, module, name.toString()) != null;
} else {
return module.getConstants().containsKey(name.toString());
}
@@ -467,7 +467,7 @@ public boolean isConstDefined(RubyModule module, RubyString name, boolean inheri
public boolean isConstDefined(RubyModule module, RubySymbol name, @SuppressWarnings("unused") UndefinedPlaceholder inherit) {
notDesignedForCompilation();

return ModuleOperations.lookupConstant(module, name.toString()) != null;
return ModuleOperations.lookupConstant(null, module, name.toString()) != null;
}

}
@@ -509,6 +509,13 @@ public RubyModule setConstant(RubyModule module, RubyString name, Object object)
return module;
}

@Specialization
public RubyModule setConstant(RubyModule module, RubySymbol name, Object object) {
notDesignedForCompilation();

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

@CoreMethod(names = "class_variable_get", minArgs = 1, maxArgs = 1)
@@ -792,13 +799,16 @@ public RubyArray nesting() {

final List<RubyModule> modules = new ArrayList<>();

RubyModule module = RubyCallStack.getCallingMethod().getDeclaringModule();
MethodLike method = RubyCallStack.getCallingMethod();
LexicalScope lexicalScope = method == null ? null : method.getSharedMethodInfo().getLexicalScope();
RubyClass object = getContext().getCoreLibrary().getObjectClass();

for (RubyModule englobing : module.lexicalAncestors()) {
if (englobing == object)
while (lexicalScope != null) {
RubyModule enclosing = lexicalScope.getLiveModule();
if (enclosing == object)
break;
modules.add(englobing);
modules.add(enclosing);
lexicalScope = lexicalScope.getParent();
}

return RubyArray.fromObjects(getContext().getCoreLibrary().getArrayClass(), modules.toArray(new Object[modules.size()]));
Original file line number Diff line number Diff line change
@@ -40,7 +40,7 @@ public Object execute(VirtualFrame frame) {

final RubyContext context = getContext();

final RubyHash env = (RubyHash) ModuleOperations.lookupConstant(getContext().getCoreLibrary().getObjectClass(), "ENV").getValue();
final RubyHash env = (RubyHash) ModuleOperations.lookupConstant(null, getContext().getCoreLibrary().getObjectClass(), "ENV").getValue();

final List<String> envp = new ArrayList<>();

Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@
import com.oracle.truffle.api.nodes.DirectCallNode;
import com.oracle.truffle.api.nodes.InvalidAssumptionException;
import com.oracle.truffle.api.utilities.BranchProfile;
import org.jruby.truffle.runtime.LexicalScope;
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
@@ -80,7 +81,7 @@ public CachedBooleanDispatchNode(CachedBooleanDispatchNode prev) {
public Object dispatch(
VirtualFrame frame,
RubyNilClass methodReceiverObject,
Object callingSelf,
LexicalScope lexicalScope,
boolean receiverObject,
Object methodName,
Object blockObject,
@@ -97,7 +98,7 @@ public Object dispatch(
return resetAndDispatch(
frame,
methodReceiverObject,
callingSelf,
lexicalScope,
receiverObject,
methodName,
CompilerDirectives.unsafeCast(blockObject, RubyProc.class, true, false),
@@ -131,7 +132,7 @@ public Object dispatch(
return resetAndDispatch(
frame,
methodReceiverObject,
callingSelf,
lexicalScope,
receiverObject,
methodName,
CompilerDirectives.unsafeCast(blockObject, RubyProc.class, true, false),
@@ -163,7 +164,7 @@ public Object dispatch(
public Object dispatch(
VirtualFrame frame,
Object methodReceiverObject,
Object callingSelf,
LexicalScope lexicalScope,
Object receiverObject,
Object methodName,
Object blockObject,
@@ -172,7 +173,7 @@ public Object dispatch(
return next.executeDispatch(
frame,
methodReceiverObject,
callingSelf,
lexicalScope,
receiverObject,
methodName,
blockObject,
Loading