Skip to content
Permalink
Browse files
Merge remote-tracking branch 'origin/master' into update_stdlib
Conflicts:
	.travis.yml
  • Loading branch information
headius committed Nov 8, 2014
2 parents 9f38db6 + 1fe2e27 commit 640a388
Show file tree
Hide file tree
Showing 47 changed files with 535 additions and 237 deletions.
@@ -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'

@@ -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");
@@ -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
@@ -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;
}
@@ -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();
}
}

@@ -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) {
@@ -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;
}
}
@@ -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
@@ -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));
}

0 comments on commit 640a388

Please sign in to comment.