Skip to content

Commit

Permalink
[Truffle] Remove MODULE_FUNCTION_FLAG_FRAME_SLOT_ID.
Browse files Browse the repository at this point in the history
* Since it is exclusive with other visibilities, we use the VISIBILITY_FRAME_SLOT_ID instead.
  • Loading branch information
eregon committed Jan 5, 2015
1 parent 4e96624 commit 7e9dd52
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 77 deletions.
39 changes: 3 additions & 36 deletions core/src/main/java/org/jruby/truffle/nodes/core/ModuleNodes.java
Expand Up @@ -947,44 +947,11 @@ public ModuleFunctionNode(ModuleFunctionNode prev) {
}

@Specialization
public RubyNilClass moduleFunction(RubyModule module, Object... args) {
public RubyModule moduleFunction(RubyModule module, Object... args) {
notDesignedForCompilation();

if (args.length == 0) {
final Frame unpacked = Truffle.getRuntime().getCallerFrame().getFrame(FrameInstance.FrameAccess.READ_WRITE, false);

final FrameSlot slot = unpacked.getFrameDescriptor().findFrameSlot(RubyModule.MODULE_FUNCTION_FLAG_FRAME_SLOT_ID);

/*
* setObject, even though it's a boolean, so we can getObject and either get the
* default Nil or the boolean value without triggering deoptimization.
*/

unpacked.setObject(slot, true);
} else {
for (Object argument : args) {
final String methodName;

if (argument instanceof RubySymbol) {
methodName = ((RubySymbol) argument).toString();
} else if (argument instanceof RubyString) {
methodName = ((RubyString) argument).toString();
} else {
throw new UnsupportedOperationException();
}

// TODO(cs): make this instance method private
final RubyMethod method = ModuleOperations.lookupMethod(module, methodName);

if (method == null) {
throw new UnsupportedOperationException();
}

module.getSingletonClass(this).addMethod(this, method.withVisibility(Visibility.PUBLIC));
}
}

return getContext().getCoreLibrary().getNilObject();
module.visibilityMethod(this, args, Visibility.MODULE_FUNCTION);
return module;
}
}

Expand Down
Expand Up @@ -9,8 +9,6 @@
*/
package org.jruby.truffle.nodes.methods;

import com.oracle.truffle.api.frame.FrameSlot;
import com.oracle.truffle.api.frame.FrameSlotTypeException;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.runtime.Visibility;
Expand All @@ -24,12 +22,12 @@
public class AddMethodNode extends RubyNode {

@Child protected RubyNode receiver;
@Child protected MethodDefinitionNode method;
@Child protected MethodDefinitionNode methodNode;

public AddMethodNode(RubyContext context, SourceSection section, RubyNode receiver, MethodDefinitionNode method, boolean topLevel) {
super(context, section);
this.receiver = receiver;
this.method = method;
this.methodNode = method;
}

@Override
Expand All @@ -38,7 +36,7 @@ public RubySymbol execute(VirtualFrame frame) {

final Object receiverObject = receiver.execute(frame);

final RubyMethod methodObject = (RubyMethod) method.execute(frame);
final RubyMethod methodObject = (RubyMethod) methodNode.execute(frame);

RubyModule module;

Expand All @@ -48,33 +46,15 @@ public RubySymbol execute(VirtualFrame frame) {
module = ((RubyBasicObject) receiverObject).getSingletonClass(this);
}

final RubyMethod methodWithDeclaringModule = methodObject.withDeclaringModule(module);
final RubyMethod method = methodObject.withDeclaringModule(module);

if (moduleFunctionFlag(frame)) {
module.addMethod(this, methodWithDeclaringModule.withVisibility(Visibility.PRIVATE));
module.getSingletonClass(this).addMethod(this, methodWithDeclaringModule.withVisibility(Visibility.PUBLIC));
if (method.getVisibility() == Visibility.MODULE_FUNCTION) {
module.addMethod(this, method.withVisibility(Visibility.PRIVATE));
module.getSingletonClass(this).addMethod(this, method.withVisibility(Visibility.PUBLIC));
} else {
module.addMethod(this, methodWithDeclaringModule);
module.addMethod(this, method);
}

return getContext().newSymbol(method.getName());
}

private boolean moduleFunctionFlag(VirtualFrame frame) {
final FrameSlot moduleFunctionFlagSlot = frame.getFrameDescriptor().findFrameSlot(RubyModule.MODULE_FUNCTION_FLAG_FRAME_SLOT_ID);

if (moduleFunctionFlagSlot == null) {
return false;
} else {
Object moduleFunctionObject;

try {
moduleFunctionObject = frame.getObject(moduleFunctionFlagSlot);
} catch (FrameSlotTypeException e) {
throw new RuntimeException(e);
}

return (moduleFunctionObject instanceof Boolean) && (boolean) moduleFunctionObject;
}
}
}
23 changes: 12 additions & 11 deletions core/src/main/java/org/jruby/truffle/runtime/core/RubyModule.java
Expand Up @@ -81,12 +81,6 @@ public static void debugModuleChain(RubyModule module) {
*/
public static final Object VISIBILITY_FRAME_SLOT_ID = new Object();

/**
* The slot within a module definition method frame where we store the implicit state that is
* the flag for whether or not new methods will be module methods (functions is the term).
*/
public static final Object MODULE_FUNCTION_FLAG_FRAME_SLOT_ID = new Object();

// The context is stored here - objects can obtain it via their class (which is a module)
private final RubyContext context;

Expand Down Expand Up @@ -388,6 +382,8 @@ public void visibilityMethod(RubyNode currentNode, Object[] arguments, Visibilit

if (arg instanceof RubySymbol) {
methodName = ((RubySymbol) arg).toString();
} else if (arg instanceof RubyString) {
methodName = ((RubyString) arg).toString();
} else {
throw new UnsupportedOperationException();
}
Expand All @@ -399,12 +395,17 @@ public void visibilityMethod(RubyNode currentNode, Object[] arguments, Visibilit
}

/*
* If the method was already defined in this class, that's fine {@link addMethod}
* will overwrite it, otherwise we do actually want to add a copy of the method with
* a different visibility to this module.
* If the method was already defined in this class, that's fine
* {@link addMethod} will overwrite it, otherwise we do actually
* want to add a copy of the method with a different visibility
* to this module.
*/

addMethod(currentNode, method.withVisibility(visibility));
if (visibility == Visibility.MODULE_FUNCTION) {
addMethod(currentNode, method.withVisibility(Visibility.PRIVATE));
getSingletonClass(currentNode).addMethod(currentNode, method.withVisibility(Visibility.PUBLIC));
} else {
addMethod(currentNode, method.withVisibility(visibility));
}
}
}
}
Expand Down
Expand Up @@ -12,6 +12,7 @@
import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.frame.MaterializedFrame;
import com.oracle.truffle.api.nodes.Node;

import org.jruby.runtime.Visibility;
import org.jruby.truffle.runtime.core.RubyClass;
import org.jruby.truffle.runtime.core.RubyModule;
Expand Down Expand Up @@ -115,7 +116,7 @@ public boolean isVisibleTo(Node currentNode, RubyClass callerClass) {
return false;

default:
return false;
throw new UnsupportedOperationException(visibility.name());
}
}

Expand Down
Expand Up @@ -201,7 +201,6 @@ public boolean getNeverAssignInParentScope() {

public void addMethodDeclarationSlots() {
frameDescriptor.addFrameSlot(RubyModule.VISIBILITY_FRAME_SLOT_ID);
frameDescriptor.addFrameSlot(RubyModule.MODULE_FUNCTION_FLAG_FRAME_SLOT_ID);
}

public SharedMethodInfo getSharedMethodInfo() {
Expand Down

0 comments on commit 7e9dd52

Please sign in to comment.