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: 9f38db6931b0
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 640a388b16c2
Choose a head ref

Commits on Nov 7, 2014

  1. Copy the full SHA
    cb1fe73 View commit details
  2. [Truffle] Implement private constants and pass all their specs.

    * The ReadConstantNode is now passed its LexicalScope.
      We still need to have it in SharedMethodInfo only for Module.nesting (if aliased).
    * Add an RubyModule.includedModules() iterator,
      as ancestors() but stopping at the first class seen.
    eregon committed Nov 7, 2014
    Copy the full SHA
    6abc370 View commit details
  3. Copy the full SHA
    719e970 View commit details
  4. Copy the full SHA
    d2ed0c1 View commit details
  5. Copy the full SHA
    b3c600d View commit details
  6. run tests/jruby.index with jruby-complete

    some tests fail they are put on allow on travis.
    mkristian committed Nov 7, 2014
    Copy the full SHA
    a8eb2bf View commit details
  7. [Truffle] Improve BooleanCastNode so to better reflect its cousin Rub…

    …yContext.isTruthy().
    
    * They do the same but the node might be more efficient.
    eregon committed Nov 7, 2014
    Copy the full SHA
    5d93cdc View commit details
  8. synchronized class loading properly - fixes #2108

    [skip ci]
    mkristian committed Nov 7, 2014
    Copy the full SHA
    ac9f2eb View commit details
  9. Copy the full SHA
    5164fc0 View commit details
  10. Copy the full SHA
    7d4e96d View commit details
  11. [Truffle] Refactor RubyClass constructors for more clarity.

    * A regular class shall always have a singleton class.
    * On usage of a singleton class (via getSingletonClass),
      it should have its own singleton class for proper lookup and consistency.
    * Also try to simplify booting classes.
    * Remove useless currentNode in unsafeSetSuperclass().
    eregon committed Nov 7, 2014
    Copy the full SHA
    a9258bb View commit details
  12. Copy the full SHA
    99067b0 View commit details
  13. Copy the full SHA
    cc69127 View commit details
  14. Copy the full SHA
    6e4f376 View commit details
  15. Copy the full SHA
    97378bc View commit details
  16. Copy the full SHA
    46a602c View commit details
  17. Copy the full SHA
    9422873 View commit details
  18. [Truffle] Singleton classes on objects should also have their own sin…

    …gleton classes.
    
    * So there is always one level of singleton classes more than the user asked,
      such that these singleton classes have a proper metaclass.
    eregon committed Nov 7, 2014
    Copy the full SHA
    ffc6708 View commit details
  19. Copy the full SHA
    9a8acd1 View commit details
  20. Copy the full SHA
    522036f View commit details
  21. Copy the full SHA
    977fbcb View commit details
  22. Revert "[Truffle] Reuse Module#instance_methods for Kernel#methods.":…

    … not working well yet.
    
    This reverts commit 522036f.
    eregon committed Nov 7, 2014
    Copy the full SHA
    fad8862 View commit details
  23. Copy the full SHA
    8a13045 View commit details

Commits on Nov 8, 2014

  1. Copy the full SHA
    1fe2e27 View commit details
  2. Merge remote-tracking branch 'origin/master' into update_stdlib

    Conflicts:
    	.travis.yml
    headius committed Nov 8, 2014
    Copy the full SHA
    640a388 View commit details
Showing with 535 additions and 237 deletions.
  1. +2 −0 .travis.yml
  2. +7 −14 core/src/main/java/org/jruby/truffle/nodes/ReadConstantNode.java
  3. +13 −4 core/src/main/java/org/jruby/truffle/nodes/cast/BooleanCastNode.java
  4. +31 −1 core/src/main/java/org/jruby/truffle/nodes/core/ClassNodes.java
  5. +1 −1 core/src/main/java/org/jruby/truffle/nodes/core/CoreMethodNodeManager.java
  6. +10 −10 core/src/main/java/org/jruby/truffle/nodes/core/KernelNodes.java
  7. +14 −12 core/src/main/java/org/jruby/truffle/nodes/core/ModuleNodes.java
  8. +12 −1 core/src/main/java/org/jruby/truffle/nodes/dispatch/DispatchNode.java
  9. +6 −19 core/src/main/java/org/jruby/truffle/nodes/objects/DefineOrGetClassNode.java
  10. +40 −17 core/src/main/java/org/jruby/truffle/nodes/objects/DefineOrGetModuleNode.java
  11. +2 −0 core/src/main/java/org/jruby/truffle/runtime/LexicalScope.java
  12. +3 −4 core/src/main/java/org/jruby/truffle/runtime/ModuleOperations.java
  13. +41 −1 core/src/main/java/org/jruby/truffle/runtime/RubyConstant.java
  14. +36 −30 core/src/main/java/org/jruby/truffle/runtime/core/CoreLibrary.java
  15. +1 −3 core/src/main/java/org/jruby/truffle/runtime/core/RubyArray.java
  16. +2 −6 core/src/main/java/org/jruby/truffle/runtime/core/RubyBasicObject.java
  17. +4 −0 core/src/main/java/org/jruby/truffle/runtime/core/RubyBignum.java
  18. +36 −21 core/src/main/java/org/jruby/truffle/runtime/core/RubyClass.java
  19. +1 −3 core/src/main/java/org/jruby/truffle/runtime/core/RubyEncoding.java
  20. +1 −3 core/src/main/java/org/jruby/truffle/runtime/core/RubyEncodingConverter.java
  21. +1 −1 core/src/main/java/org/jruby/truffle/runtime/core/RubyException.java
  22. +0 −5 core/src/main/java/org/jruby/truffle/runtime/core/RubyFalseClass.java
  23. +1 −2 core/src/main/java/org/jruby/truffle/runtime/core/RubyFiber.java
  24. +1 −1 core/src/main/java/org/jruby/truffle/runtime/core/RubyHash.java
  25. +45 −8 core/src/main/java/org/jruby/truffle/runtime/core/RubyModule.java
  26. +0 −5 core/src/main/java/org/jruby/truffle/runtime/core/RubyNilClass.java
  27. +1 −2 core/src/main/java/org/jruby/truffle/runtime/core/RubyProc.java
  28. +1 −2 core/src/main/java/org/jruby/truffle/runtime/core/RubyRegexp.java
  29. +1 −1 core/src/main/java/org/jruby/truffle/runtime/core/RubyString.java
  30. +1 −1 core/src/main/java/org/jruby/truffle/runtime/core/RubyThread.java
  31. +1 −1 core/src/main/java/org/jruby/truffle/runtime/core/RubyTime.java
  32. +6 −6 core/src/main/java/org/jruby/truffle/runtime/rubinius/RubiniusLibrary.java
  33. +1 −1 core/src/main/java/org/jruby/truffle/runtime/subsystems/FeatureManager.java
  34. +18 −10 core/src/main/java/org/jruby/truffle/translator/BodyTranslator.java
  35. +5 −3 core/src/main/java/org/jruby/truffle/translator/TranslatorDriver.java
  36. +9 −7 core/src/main/java/org/jruby/util/JRubyClassLoader.java
  37. +1 −1 maven/pom.rb
  38. +6 −0 maven/pom.xml
  39. +6 −4 pom.rb
  40. +10 −0 pom.xml
  41. +0 −2 spec/truffle/tags/core/module/instance_methods_tags.txt
  42. +0 −12 spec/truffle/tags/language/constants_tags.txt
  43. +0 −1 spec/truffle/tags/language/module_tags.txt
  44. +0 −9 spec/truffle/tags/language/singleton_class_tags.txt
  45. +23 −0 test/pom.rb
  46. +132 −0 test/pom.xml
  47. +2 −2 tool/build-graal-bundles.sh
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@ env:
- JAVA_OPTS="-XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Djruby.cext.enabled=false"
matrix:
- TARGET='-Ptest'
- TARGET='-Pjruby_complete_jar_jruby'
- TARGET='-Prake -Dtask=test:rubicon'
- TARGET='-Prake -Dtask=test:jruby'
- TARGET='-Prake -Dtask=test:mri'
@@ -53,6 +54,7 @@ matrix:
allow_failures:
- env: TARGET='-Pcomplete'
- env: TARGET='-Prake -Dtask=spec:jrubyc'
- env: TARGET='-Pjruby_complete_jar_jruby'
- env: TARGET='-Pj2ee'
- env: TARGET='-Prake -Dtask=spec:profiler'

21 changes: 7 additions & 14 deletions core/src/main/java/org/jruby/truffle/nodes/ReadConstantNode.java
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.source.*;
import com.oracle.truffle.api.frame.*;
import org.jruby.truffle.nodes.core.TruffleDebugNodes;
import org.jruby.truffle.nodes.dispatch.Dispatch;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNode;
import org.jruby.truffle.runtime.*;
@@ -23,24 +24,18 @@
public class ReadConstantNode extends RubyNode {

private final String name;
private final LexicalScope lexicalScope;
@Child protected RubyNode receiver;
@Child protected DispatchHeadNode dispatch;

public ReadConstantNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver) {
public ReadConstantNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, LexicalScope lexicalScope) {
super(context, sourceSection);
this.name = name;
this.lexicalScope = lexicalScope;
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);
@@ -50,8 +45,6 @@ public Object execute(VirtualFrame frame) {
throw new RaiseException(getContext().getCoreLibrary().typeErrorIsNotA(receiverObject.toString(), "class/module", this));
}

LexicalScope lexicalScope = getLexicalScope(frame);

return dispatch.dispatch(
frame,
getContext().getCoreLibrary().getNilObject(),
@@ -97,10 +90,10 @@ public Object isDefined(VirtualFrame frame) {
throw e;
}

LexicalScope lexicalScope = getLexicalScope(frame);
RubyConstant constant = ModuleOperations.lookupConstant(lexicalScope, (RubyModule) receiverObject, name);
RubyModule module = (RubyModule) receiverObject; // TODO(cs): cast
RubyConstant constant = ModuleOperations.lookupConstant(context, lexicalScope, module, name);

if (constant == null) {
if (constant == null || !constant.isVisibleTo(context, lexicalScope, module)) {
return getContext().getCoreLibrary().getNilObject();
} else {
return context.makeString("constant");
Original file line number Diff line number Diff line change
@@ -21,8 +21,7 @@
import java.math.BigInteger;

/**
* Casts a value into a boolean. Works at the language level, so doesn't call any Ruby methods to
* cast non-core or monkey-patched objects.
* Casts a value into a boolean.
*/
@NodeChild(value = "child", type = RubyNode.class)
public abstract class BooleanCastNode extends RubyNode {
@@ -40,6 +39,11 @@ public boolean doNil(@SuppressWarnings("unused") RubyNilClass nil) {
return false;
}

@Specialization
public boolean doFalse(@SuppressWarnings("unused") RubyFalseClass falseObject) {
return false;
}

@Specialization
public boolean doBoolean(boolean value) {
return value;
@@ -65,9 +69,14 @@ public boolean doFloat(double value) {
return true;
}

@Specialization
@Specialization(guards = "neitherNilNorFalse")
public boolean doBasicObject(RubyBasicObject object) {
return object.isTrue();
return true;
}

protected boolean neitherNilNorFalse(RubyBasicObject object) {
return object != getContext().getCoreLibrary().getNilObject() &&
object != getContext().getCoreLibrary().getFalseObject();
}

@Override
32 changes: 31 additions & 1 deletion core/src/main/java/org/jruby/truffle/nodes/core/ClassNodes.java
Original file line number Diff line number Diff line change
@@ -9,13 +9,16 @@
*/
package org.jruby.truffle.nodes.core;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNode;
import org.jruby.truffle.runtime.ModuleOperations;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.UndefinedPlaceholder;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyClass;
import org.jruby.truffle.runtime.core.RubyProc;
import org.jruby.truffle.runtime.core.RubyString;
@@ -26,18 +29,45 @@
@CoreClass(name = "Class")
public abstract class ClassNodes {

@CoreMethod(names = "allocate")
public abstract static class AllocateNode extends CoreMethodNode {

public AllocateNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public AllocateNode(AllocateNode prev) {
super(prev);
}

public abstract RubyBasicObject executeAllocate(VirtualFrame frame, RubyClass rubyClass);

@Specialization
public RubyBasicObject allocate(RubyClass rubyClass) {
if (rubyClass.isSingleton()) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().typeError("can't create instance of singleton class", this));
}
return rubyClass.newInstance(this);
}

}

@CoreMethod(names = "new", needsBlock = true, argumentsAsArray = true)
public abstract static class NewNode extends CoreMethodNode {

@Child protected AllocateNode allocateNode;
@Child protected DispatchHeadNode initialize;

public NewNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
allocateNode = ClassNodesFactory.AllocateNodeFactory.create(context, sourceSection, new RubyNode[]{null});
initialize = DispatchHeadNode.onSelf(context);
}

public NewNode(NewNode prev) {
super(prev);
allocateNode = prev.allocateNode;
initialize = prev.initialize;
}

@@ -52,7 +82,7 @@ public RubyBasicObject newInstance(VirtualFrame frame, RubyClass rubyClass, Obje
}

private RubyBasicObject doNewInstance(VirtualFrame frame, RubyClass rubyClass, Object[] args, RubyProc block) {
final RubyBasicObject instance = rubyClass.newInstance(this);
final RubyBasicObject instance = allocateNode.executeAllocate(frame, rubyClass);
initialize.call(frame, instance, "initialize", block, args);
return instance;
}
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(null, module, moduleName).getValue();
module = (RubyModule) ModuleOperations.lookupConstant(context, null, module, moduleName).getValue();
}
}

20 changes: 10 additions & 10 deletions core/src/main/java/org/jruby/truffle/nodes/core/KernelNodes.java
Original file line number Diff line number Diff line change
@@ -1094,23 +1094,23 @@ public MethodsNode(MethodsNode prev) {
}

@Specialization
public RubyArray methods(RubyObject self, boolean includeInherited) {
notDesignedForCompilation();

if (!includeInherited) {
getContext().getRuntime().getWarnings().warn(IRubyWarnings.ID.TRUFFLE, Truffle.getRuntime().getCallerFrame().getCallNode().getEncapsulatingSourceSection().getSource().getName(), Truffle.getRuntime().getCallerFrame().getCallNode().getEncapsulatingSourceSection().getStartLine(), "Object#methods always returns inherited methods at the moment");
}

return methods(self, UndefinedPlaceholder.INSTANCE);
public RubyArray methods(RubyObject self, @SuppressWarnings("unused") UndefinedPlaceholder unused) {
return methods(self, true);
}

@Specialization
public RubyArray methods(RubyObject self, @SuppressWarnings("unused") UndefinedPlaceholder includeInherited) {
public RubyArray methods(RubyObject self, boolean includeInherited) {
notDesignedForCompilation();

final RubyArray array = new RubyArray(self.getContext().getCoreLibrary().getArrayClass());

final Map<String, RubyMethod> methods = ModuleOperations.getAllMethods(self.getMetaClass());
Map<String, RubyMethod> methods;

if (includeInherited) {
methods = ModuleOperations.getAllMethods(self.getMetaClass());
} else {
methods = self.getMetaClass().getMethods();
}

for (RubyMethod method : methods.values()) {
if (method.getVisibility() == Visibility.PUBLIC || method.getVisibility() == Visibility.PROTECTED) {
26 changes: 14 additions & 12 deletions core/src/main/java/org/jruby/truffle/nodes/core/ModuleNodes.java
Original file line number Diff line number Diff line change
@@ -37,6 +37,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@CoreClass(name = "Module")
public abstract class ModuleNodes {
@@ -491,15 +492,15 @@ public ConstDefinedNode(ConstDefinedNode prev) {
public boolean isConstDefined(RubyModule module, RubyString name, @SuppressWarnings("unused") UndefinedPlaceholder inherit) {
notDesignedForCompilation();

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

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

if (inherit) {
return ModuleOperations.lookupConstant(null, module, name.toString()) != null;
return ModuleOperations.lookupConstant(getContext(), null, module, name.toString()) != null;
} else {
return module.getConstants().containsKey(name.toString());
}
@@ -509,7 +510,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(null, module, name.toString()) != null;
return ModuleOperations.lookupConstant(getContext(), null, module, name.toString()) != null;
}

}
@@ -1112,28 +1113,29 @@ public InstanceMethodsNode(InstanceMethodsNode prev) {
public RubyArray instanceMethods(RubyModule module, UndefinedPlaceholder argument) {
notDesignedForCompilation();

return instanceMethods(module, false);
return instanceMethods(module, true);
}

@Specialization
public RubyArray instanceMethods(RubyModule module, boolean includeAncestors) {
notDesignedForCompilation();

final List<RubyMethod> methods = new ArrayList<>(module.getMethods().values());
Map<String, RubyMethod> methods;

if (includeAncestors) {
for (RubyModule parent : module.parentAncestors()) {
methods.addAll(parent.getMethods().values());
}
methods = ModuleOperations.getAllMethods(module);
} else {
methods = module.getMethods();
}

final RubyArray array = new RubyArray(getContext().getCoreLibrary().getArrayClass());
for (RubyMethod method : methods) {
if (method.getVisibility() != Visibility.PRIVATE){
RubySymbol m = getContext().newSymbol(method.getName());
for (RubyMethod method : methods.values()) {
if (method.getVisibility() != Visibility.PRIVATE && !method.isUndefined()) {
// TODO(CS): shoudln't be using this
array.slowPush(m);
array.slowPush(getContext().newSymbol(method.getName()));
}
}

return array;
}
}
Original file line number Diff line number Diff line change
@@ -60,7 +60,18 @@ protected RubyConstant lookupConstant(
String name,
boolean ignoreVisibility,
Dispatch.DispatchAction dispatchAction) {
return ModuleOperations.lookupConstant(lexicalScope, module, name);
RubyConstant constant = ModuleOperations.lookupConstant(getContext(), lexicalScope, module, name);

// If no constant was found, use #const_missing
if (constant == null) {
return null;
}

if (!ignoreVisibility && !constant.isVisibleTo(getContext(), lexicalScope, module)) {
throw new RaiseException(getContext().getCoreLibrary().nameErrorPrivateConstant(module, name, this));
}

return constant;
}

@CompilerDirectives.SlowPath
Original file line number Diff line number Diff line change
@@ -11,7 +11,6 @@

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.runtime.*;
import org.jruby.truffle.runtime.control.*;
@@ -20,16 +19,12 @@
/**
* Define a new class, or get the existing one of the same name.
*/
public class DefineOrGetClassNode extends RubyNode {
public class DefineOrGetClassNode extends DefineOrGetModuleNode {

private final String name;
@Child protected RubyNode lexicalParentModule;
@Child protected RubyNode superClass;

public DefineOrGetClassNode(RubyContext context, SourceSection sourceSection, String name, RubyNode lexicalParentModule, RubyNode superClass) {
super(context, sourceSection);
this.name = name;
this.lexicalParentModule = lexicalParentModule;
super(context, sourceSection, name, lexicalParentModule);
this.superClass = superClass;
}

@@ -39,17 +34,10 @@ public Object execute(VirtualFrame frame) {

final RubyContext context = getContext();

RubyModule lexicalParentModuleObject;

try {
lexicalParentModuleObject = lexicalParentModule.executeRubyModule(frame);
} catch (UnexpectedResultException e) {
throw new RaiseException(context.getCoreLibrary().typeErrorIsNotA(e.getResult().toString(), "module", this));
}

// Look for a current definition of the class, or create a new one

final RubyConstant constant = lexicalParentModuleObject.getConstants().get(name);
RubyModule lexicalParent = getLexicalParentModule(frame);
final RubyConstant constant = lookupForExistingModule(frame, lexicalParent);

RubyClass definingClass;
RubyClass superClassObject = getRubySuperClass(frame, context);
@@ -60,15 +48,14 @@ public Object execute(VirtualFrame frame) {
} else if (superClassObject instanceof RubyString.RubyStringClass) {
definingClass = new RubyString.RubyStringClass(superClassObject);
} else {
definingClass = new RubyClass(this, lexicalParentModuleObject, superClassObject, name);
definingClass = new RubyClass(lexicalParent, superClassObject, name);
}

lexicalParentModuleObject.setConstant(this, name, definingClass);
lexicalParent.setConstant(this, name, definingClass);
} else {
if (constant.getValue() instanceof RubyClass) {
definingClass = (RubyClass) constant.getValue();
checkSuperClassCompatibility(context, superClassObject, definingClass);

} else {
throw new RaiseException(context.getCoreLibrary().typeErrorIsNotA(constant.getValue().toString(), "class", this));
}
Loading