Skip to content

Commit

Permalink
[Truffle] Add allocate specialization, re-order receiver, name arguments
Browse files Browse the repository at this point in the history
Brandon Fish committed Jul 22, 2016

Verified

This commit was signed with the committer’s verified signature.
1 parent 79154fc commit efa0c90
Showing 10 changed files with 52 additions and 38 deletions.
2 changes: 1 addition & 1 deletion truffle/src/main/java/org/jruby/truffle/Layouts.java
Original file line number Diff line number Diff line change
@@ -123,7 +123,7 @@ public abstract class Layouts {
public static final MethodLayout METHOD = MethodLayoutImpl.INSTANCE;
public static final ModuleLayout MODULE = ModuleLayoutImpl.INSTANCE;
public static final MutexLayout MUTEX = MutexLayoutImpl.INSTANCE;
public static final NameErrorLayout NAME_ERROR_LAYOUT = NameErrorLayoutImpl.INSTANCE;
public static final NameErrorLayout NAME_ERROR = NameErrorLayoutImpl.INSTANCE;
public static final ObjectRangeLayout OBJECT_RANGE = ObjectRangeLayoutImpl.INSTANCE;
public static final PointerLayout POINTER = PointerLayoutImpl.INSTANCE;
public static final ProcLayout PROC = ProcLayoutImpl.INSTANCE;
Original file line number Diff line number Diff line change
@@ -395,7 +395,7 @@ public CoreLibrary(RubyContext context) {

// StandardError > NameError
nameErrorClass = defineClass(standardErrorClass, "NameError");
Layouts.CLASS.setInstanceFactoryUnsafe(nameErrorClass, Layouts.NAME_ERROR_LAYOUT.createNameErrorShape(nameErrorClass, nameErrorClass));
Layouts.CLASS.setInstanceFactoryUnsafe(nameErrorClass, Layouts.NAME_ERROR.createNameErrorShape(nameErrorClass, nameErrorClass));
noMethodErrorClass = defineClass(nameErrorClass, "NoMethodError");

// StandardError > SystemCallError
Original file line number Diff line number Diff line change
@@ -411,7 +411,7 @@ public DynamicObject typeError(String message, Node currentNode, Throwable javaT

@TruffleBoundary
public DynamicObject nameErrorConstantNotDefined(DynamicObject module, String name, Node currentNode) {
return nameError(String.format("constant %s::%s not defined", Layouts.MODULE.getFields(module).getName(), name), name, null, currentNode);
return nameError(String.format("constant %s::%s not defined", Layouts.MODULE.getFields(module).getName(), name), null, name, currentNode);
}

@TruffleBoundary
@@ -423,103 +423,103 @@ public DynamicObject nameErrorUninitializedConstant(DynamicObject module, String
} else {
message = String.format("uninitialized constant %s::%s", Layouts.MODULE.getFields(module).getName(), name);
}
return nameError(message, name, module, currentNode);
return nameError(message, module, name, currentNode);
}

@TruffleBoundary
public DynamicObject nameErrorUninitializedClassVariable(DynamicObject module, String name, Node currentNode) {
assert RubyGuards.isRubyModule(module);
return nameError(String.format("uninitialized class variable %s in %s", name, Layouts.MODULE.getFields(module).getName()), name, module, currentNode);
return nameError(String.format("uninitialized class variable %s in %s", name, Layouts.MODULE.getFields(module).getName()), module, name, currentNode);
}

@TruffleBoundary
public DynamicObject nameErrorPrivateConstant(DynamicObject module, String name, Node currentNode) {
return nameError(String.format("private constant %s::%s referenced", Layouts.MODULE.getFields(module).getName(), name), name, module, currentNode);
return nameError(String.format("private constant %s::%s referenced", Layouts.MODULE.getFields(module).getName(), name), module, name, currentNode);
}

@TruffleBoundary
public DynamicObject nameErrorInstanceNameNotAllowable(String name, Object receiver, Node currentNode) {
return nameError(String.format("`%s' is not allowable as an instance variable name", name), name, receiver, currentNode);
return nameError(String.format("`%s' is not allowable as an instance variable name", name), receiver, name, currentNode);
}

@TruffleBoundary
public DynamicObject nameErrorInstanceVariableNotDefined(String name, Object receiver, Node currentNode) {
return nameError(String.format("instance variable %s not defined", name), name, receiver, currentNode);
return nameError(String.format("instance variable %s not defined", name), receiver, name, currentNode);
}

@TruffleBoundary
public DynamicObject nameErrorReadOnly(String name, Node currentNode) {
return nameError(String.format("%s is a read-only variable", name), name, null, currentNode);
return nameError(String.format("%s is a read-only variable", name), null, name, currentNode);
}

@TruffleBoundary
public DynamicObject nameErrorUndefinedLocalVariableOrMethod(String name, Object receiver, Node currentNode) {
// TODO: should not be just the class, but rather sth like name_err_mesg_to_str() in MRI error.c
String className = Layouts.MODULE.getFields(context.getCoreLibrary().getLogicalClass(receiver)).getName();
return nameError(String.format("undefined local variable or method `%s' for %s", name, className), name, receiver, currentNode);
return nameError(String.format("undefined local variable or method `%s' for %s", name, className), receiver, name, currentNode);
}

@TruffleBoundary
public DynamicObject nameErrorUndefinedMethod(String name, DynamicObject module, Node currentNode) {
assert RubyGuards.isRubyModule(module);
return nameError(String.format("undefined method `%s' for %s", name, Layouts.MODULE.getFields(module).getName()), name, module, currentNode);
return nameError(String.format("undefined method `%s' for %s", name, Layouts.MODULE.getFields(module).getName()), module, name, currentNode);
}

@TruffleBoundary
public DynamicObject nameErrorMethodNotDefinedIn(DynamicObject module, String name, Node currentNode) {
return nameError(String.format("method `%s' not defined in %s", name, Layouts.MODULE.getFields(module).getName()), name, module, currentNode);
return nameError(String.format("method `%s' not defined in %s", name, Layouts.MODULE.getFields(module).getName()), module, name, currentNode);
}

@TruffleBoundary
public DynamicObject nameErrorPrivateMethod(String name, DynamicObject module, Node currentNode) {
return nameError(String.format("method `%s' for %s is private", name, Layouts.MODULE.getFields(module).getName()), name, module, currentNode);
return nameError(String.format("method `%s' for %s is private", name, Layouts.MODULE.getFields(module).getName()), module, name, currentNode);
}

@TruffleBoundary
public DynamicObject nameErrorLocalVariableNotDefined(String name, DynamicObject binding, Node currentNode) {
assert RubyGuards.isRubyBinding(binding);
return nameError(String.format("local variable `%s' not defined for %s", name, binding.toString()), name, binding, currentNode);
return nameError(String.format("local variable `%s' not defined for %s", name, binding.toString()), binding, name, currentNode);
}

@TruffleBoundary
public DynamicObject nameErrorClassVariableNotDefined(String name, DynamicObject module, Node currentNode) {
assert RubyGuards.isRubyModule(module);
return nameError(String.format("class variable `%s' not defined for %s", name, Layouts.MODULE.getFields(module).getName()), name, module, currentNode);
return nameError(String.format("class variable `%s' not defined for %s", name, Layouts.MODULE.getFields(module).getName()), module, name, currentNode);
}

@TruffleBoundary
public DynamicObject nameErrorImportNotFound(String name, Node currentNode) {
return nameError(String.format("import '%s' not found", name), name, null, currentNode);
return nameError(String.format("import '%s' not found", name), null, name, currentNode);
}

@TruffleBoundary
public DynamicObject nameError(String message, String name, Object receiver, Node currentNode) {
public DynamicObject nameError(String message, Object receiver, String name, Node currentNode) {
final DynamicObject nameString = StringOperations.createString(context, StringOperations.encodeRope(message, UTF8Encoding.INSTANCE));
DynamicObject nameError = ExceptionOperations.createNameError(context.getCoreLibrary().getNameErrorClass(), nameString, context.getCallStack().getBacktrace(currentNode), context.getSymbolTable().getSymbol(name), receiver);
DynamicObject nameError = ExceptionOperations.createNameError(context.getCoreLibrary().getNameErrorClass(), nameString, context.getCallStack().getBacktrace(currentNode), receiver, context.getSymbolTable().getSymbol(name));
return nameError;
}

// NoMethodError

@TruffleBoundary
public DynamicObject noMethodError(String message, String name, Object receiver, Node currentNode) {
public DynamicObject noMethodError(String message, Object receiver, String name, Node currentNode) {
final DynamicObject messageString = StringOperations.createString(context, StringOperations.encodeRope(message, UTF8Encoding.INSTANCE));
DynamicObject noMethodError = ExceptionOperations.createNameError(context.getCoreLibrary().getNoMethodErrorClass(), messageString, context.getCallStack().getBacktrace(currentNode), context.getSymbolTable().getSymbol(name), receiver);
DynamicObject noMethodError = ExceptionOperations.createNameError(context.getCoreLibrary().getNoMethodErrorClass(), messageString, context.getCallStack().getBacktrace(currentNode), receiver, context.getSymbolTable().getSymbol(name));
return noMethodError;
}

@TruffleBoundary
public DynamicObject noSuperMethodOutsideMethodError(Node currentNode) {
final DynamicObject messageString = StringOperations.createString(context, StringOperations.encodeRope("super called outside of method", UTF8Encoding.INSTANCE));
// TODO BJF Jul 21, 2016 Review to add receiver
DynamicObject noMethodError = ExceptionOperations.createNameError(context.getCoreLibrary().getNoMethodErrorClass(), messageString, context.getCallStack().getBacktrace(currentNode), context.getSymbolTable().getSymbol("<unknown>"), null);
DynamicObject noMethodError = ExceptionOperations.createNameError(context.getCoreLibrary().getNoMethodErrorClass(), messageString, context.getCallStack().getBacktrace(currentNode), null, context.getSymbolTable().getSymbol("<unknown>"));
// FIXME: the name of the method is not known in this case currently
return noMethodError;
}

@TruffleBoundary
public DynamicObject noSuperMethodError(String name, Object self, Node currentNode) {
return noMethodError(String.format("super: no superclass method `%s'", name), name, self, currentNode);
return noMethodError(String.format("super: no superclass method `%s'", name), self, name, currentNode);
}

@TruffleBoundary
@@ -531,13 +531,13 @@ public DynamicObject noMethodErrorOnReceiver(String name, Object receiver, Node
final boolean hasInspect = ModuleOperations.lookupMethod(logicalClass, "inspect", Visibility.PUBLIC) != null;
final Object stringRepresentation = hasInspect ? context.send(receiver, "inspect", null) : context.getCoreLibrary().getNilObject();

return noMethodError(String.format("undefined method `%s' for %s:%s", name, stringRepresentation, moduleName), name, receiver, currentNode);
return noMethodError(String.format("undefined method `%s' for %s:%s", name, stringRepresentation, moduleName), receiver, name, currentNode);
}

@TruffleBoundary
public DynamicObject privateMethodError(String name, Object self, Node currentNode) {
String className = Layouts.MODULE.getFields(context.getCoreLibrary().getLogicalClass(self)).getName();
return noMethodError(String.format("private method `%s' called for %s", name, className), name, self, currentNode);
return noMethodError(String.format("private method `%s' called for %s", name, className), self, name, currentNode);
}

// LoadError
Original file line number Diff line number Diff line change
@@ -133,9 +133,23 @@ public AllocateNode(RubyContext context, SourceSection sourceSection) {
allocateObjectNode = AllocateObjectNodeGen.create(context, sourceSection, null, null);
}

@Specialization
@Specialization(guards = "!isNameError(rubyClass)")
public DynamicObject allocate(DynamicObject rubyClass) {
return allocateObjectNode.allocate(rubyClass, nil(), null, nil(), null);
return allocateObjectNode.allocate(rubyClass, nil(), null, nil());
}

@Specialization(guards = "isNameError(rubyClass)")
public DynamicObject allocateNameError(DynamicObject rubyClass) {
return allocateObjectNode.allocate(rubyClass, nil(), null, null, nil());
}

public static boolean isNameError(DynamicObject rubyClass){
for(DynamicObject ancestor : Layouts.MODULE.getFields(rubyClass).ancestors()){
if(Layouts.MODULE.getFields(ancestor).getName().equals("NameError")){
return true;
}
}
return false;
}

}
Original file line number Diff line number Diff line change
@@ -50,8 +50,8 @@ public static DynamicObject createSystemCallError(DynamicObject rubyClass, Objec
return Layouts.SYSTEM_CALL_ERROR.createSystemCallError(Layouts.CLASS.getInstanceFactory(rubyClass), message, backtrace, errno);
}

public static DynamicObject createNameError(DynamicObject rubyClass, Object message, Backtrace backtrace, Object name, Object receiver) {
return Layouts.NAME_ERROR_LAYOUT.createNameError(Layouts.CLASS.getInstanceFactory(rubyClass), message, backtrace, name, receiver);
public static DynamicObject createNameError(DynamicObject rubyClass, Object message, Backtrace backtrace, Object receiver, Object name) {
return Layouts.NAME_ERROR.createNameError(Layouts.CLASS.getInstanceFactory(rubyClass), message, backtrace, receiver, name);
}

}
Original file line number Diff line number Diff line change
@@ -26,8 +26,8 @@ DynamicObject createNameError(
DynamicObjectFactory factory,
Object message,
@Nullable Backtrace backtrace,
Object name,
@Nullable Object receiver);
@Nullable Object receiver,
Object name);

Object getName(DynamicObject object);
void setName(DynamicObject object, Object value);
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ public abstract static class NameNode extends CoreMethodArrayArgumentsNode {

@Specialization
public Object name(DynamicObject self) {
return Layouts.NAME_ERROR_LAYOUT.getName(self);
return Layouts.NAME_ERROR.getName(self);
}

}
@@ -37,7 +37,7 @@ public abstract static class ReceiverNode extends CoreMethodArrayArgumentsNode {

@Specialization
public Object receiver(DynamicObject self) {
final Object receiver = Layouts.NAME_ERROR_LAYOUT.getReceiver(self);
final Object receiver = Layouts.NAME_ERROR.getReceiver(self);

// TODO BJF July 21, 2016 Implement name error in message field

@@ -54,7 +54,7 @@ public abstract static class NameSetNode extends PrimitiveArrayArgumentsNode {

@Specialization
public Object setName(DynamicObject error, Object name) {
Layouts.NAME_ERROR_LAYOUT.setName(error, name);
Layouts.NAME_ERROR.setName(error, name);
return name;
}

Original file line number Diff line number Diff line change
@@ -522,7 +522,7 @@ public AutoloadNode(RubyContext context, SourceSection sourceSection) {
@Specialization(guards = "isRubyString(filename)")
public DynamicObject autoload(DynamicObject module, String name, DynamicObject filename) {
if (!IdUtil.isValidConstantName19(name)) {
throw new RaiseException(coreExceptions().nameError(String.format("autoload must be constant name: %s", name), name, module, this));
throw new RaiseException(coreExceptions().nameError(String.format("autoload must be constant name: %s", name), module, name, this));
}

if (isEmptyNode.executeIsEmpty(filename)) {
@@ -964,7 +964,7 @@ public RubyNode coerceToString(RubyNode name) {
@Specialization
public Object setConstant(DynamicObject module, String name, Object value) {
if (!IdUtil.isValidConstantName19(name)) {
throw new RaiseException(coreExceptions().nameError(String.format("wrong constant name %s", name), name, module, this));
throw new RaiseException(coreExceptions().nameError(String.format("wrong constant name %s", name), module, name, this));
}

Layouts.MODULE.getFields(module).setConstant(getContext(), this, name, value);
Original file line number Diff line number Diff line change
@@ -183,7 +183,7 @@ public static RubyConstant lookupScopedConstant(RubyContext context, DynamicObje

final String lastSegment = fullName.substring(start);
if (!IdUtil.isValidConstantName19(lastSegment)) {
throw new RaiseException(context.getCoreExceptions().nameError(String.format("wrong constant name %s", fullName), fullName, module, currentNode));
throw new RaiseException(context.getCoreExceptions().nameError(String.format("wrong constant name %s", fullName), module, fullName, currentNode));
}

return lookupConstantWithInherit(context, module, lastSegment, inherit, currentNode);
@@ -194,7 +194,7 @@ public static RubyConstant lookupConstantWithInherit(RubyContext context, Dynami
assert RubyGuards.isRubyModule(module);

if (!IdUtil.isValidConstantName19(name)) {
throw new RaiseException(context.getCoreExceptions().nameError(String.format("wrong constant name %s", name), name, module, currentNode));
throw new RaiseException(context.getCoreExceptions().nameError(String.format("wrong constant name %s", name), module, name, currentNode));
}

if (inherit) {
Original file line number Diff line number Diff line change
@@ -94,7 +94,7 @@ private Object doMissingConstant(
boolean isValidConstantName,
DynamicObject symbolName) {
if (!isValidConstantName) {
throw new RaiseException(coreExceptions().nameError(formatError(name), name, module, this));
throw new RaiseException(coreExceptions().nameError(formatError(name), module, name, this));
}

if (constMissingNode == null) {

0 comments on commit efa0c90

Please sign in to comment.