Skip to content
Permalink
Browse files
[Truffle] Lots of work on STDIN, STDOUT, STDERR.
  • Loading branch information
chrisseaton committed Dec 13, 2014
1 parent 0755620 commit f16b8f7dcb88c452dfe97004cdbc465e6e890660
@@ -233,7 +233,18 @@ public Object append(Object store, int index, Object value) {

replace(new ObjectArrayBuilderNode(getContext(), expectedLength));

final Object[] newStore = ArrayUtils.box((int[]) store);
// TODO(CS): not sure why this happens - need to investigate

final Object[] newStore;

if (store instanceof int[]) {
newStore = ArrayUtils.box((int[]) store);
} else if (store instanceof Object[]) {
newStore = (Object[]) store;
} else {
throw new UnsupportedOperationException();
}

newStore[index] = value;
return newStore;
}
@@ -2117,9 +2117,10 @@ public RubyString inspect(VirtualFrame frame, RubyArray array) {
builder.append(", ");
}

// TODO(CS): to string
// TODO(CS): cast

builder.append(inspect.call(frame, objects[n], "inspect", null));
final RubyString string = (RubyString) inspect.call(frame, objects[n], "inspect", null);
builder.append(string.getBytes().toString());
}

builder.append("]");
@@ -14,6 +14,7 @@
import com.oracle.truffle.api.dsl.Specialization;
import org.jcodings.Encoding;
import org.jcodings.EncodingDB;
import org.jcodings.specific.ASCIIEncoding;
import org.jcodings.specific.UTF8Encoding;
import org.jcodings.util.CaseInsensitiveBytesHash;
import org.jcodings.util.Hash;
@@ -244,7 +245,9 @@ public ToSNode(ToSNode prev) {
@CompilerDirectives.SlowPath
@Specialization
public RubyString toS(RubyEncoding encoding) {
return getContext().makeString(encoding.getName());
final ByteList name = encoding.getName().dup();
name.setEncoding(ASCIIEncoding.INSTANCE);
return getContext().makeString(name);
}
}

@@ -262,12 +265,13 @@ public InspectNode(InspectNode prev) {
@CompilerDirectives.SlowPath
@Specialization
public RubyString toS(RubyEncoding encoding) {
RubyString name = getContext().makeString(encoding.getName());
final ByteList nameByteList = encoding.getName().dup();
nameByteList.setEncoding(ASCIIEncoding.INSTANCE);

if (encoding.isDummy()) {
return getContext().makeString(String.format("#<Encoding:%s (dummy)>", name.toString()));
return getContext().makeString(String.format("#<Encoding:%s (dummy)>", nameByteList.toString()));
} else {
return getContext().makeString(String.format("#<Encoding:%s>", name.toString()));
return getContext().makeString(String.format("#<Encoding:%s>", nameByteList.toString()));
}
}
}
@@ -547,7 +547,8 @@ public InspectNode(InspectNode prev) {
public RubyString inspect(RubyString string) {
notDesignedForCompilation();

return getContext().makeString(org.jruby.RubyString.inspect19(getContext().getRuntime(), string.getBytes()).toString());
final org.jruby.RubyString inspected = (org.jruby.RubyString) org.jruby.RubyString.inspect19(getContext().getRuntime(), string.getBytes());
return getContext().makeString(inspected.getByteList());
}
}

@@ -0,0 +1,44 @@
/*
* Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.nodes.globals;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.ModuleOperations;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyMatchData;
import org.jruby.truffle.runtime.core.RubyNilClass;

public class CheckStdoutVariableTypeNode extends RubyNode {

@Child protected RubyNode child;

public CheckStdoutVariableTypeNode(RubyContext context, SourceSection sourceSection, RubyNode child) {
super(context, sourceSection);
this.child = child;
}

public Object execute(VirtualFrame frame) {
notDesignedForCompilation();

final Object childValue = child.execute(frame);

if (childValue == getContext().getCoreLibrary().getNilObject() || ModuleOperations.lookupMethod(getContext().getCoreLibrary().getMetaClass(childValue), "write") == null) {
throw new RaiseException(getContext().getCoreLibrary().typeError(String.format("$stdout must have write method, %s given", getContext().getCoreLibrary().getLogicalClass(childValue).getName()), this));
}

return childValue;
}

}
@@ -315,16 +315,6 @@ public void initialize() {
}

public void initializeAfterMethodsAdded() {
// Just create a dummy object for $stdout - we can use Kernel#print and a special method TruffleDebug.flush_stdout

final RubyBasicObject stdout = new RubyBasicObject(objectClass);
stdout.getSingletonClass(null).addMethod(null, ModuleOperations.lookupMethod(stdout.getMetaClass(), "print").withVisibility(Visibility.PUBLIC));
stdout.getSingletonClass(null).addMethod(null, ModuleOperations.lookupMethod(truffleDebugModule.getSingletonClass(null), "flush_stdout").withNewName("flush"));
globalVariablesObject.setInstanceVariable("$stdout", stdout);

objectClass.setConstant(null, "STDIN", new RubyBasicObject(objectClass));
objectClass.setConstant(null, "STDOUT", stdout);
objectClass.setConstant(null, "STDERR", stdout);
objectClass.setConstant(null, "RUBY_RELEASE_DATE", context.makeString(Constants.COMPILE_DATE));
objectClass.setConstant(null, "RUBY_DESCRIPTION", context.makeString(OutputStrings.getVersionString()));

@@ -38,6 +38,7 @@
import org.jruby.truffle.nodes.control.WhileNode;
import org.jruby.truffle.nodes.core.*;
import org.jruby.truffle.nodes.globals.CheckMatchVariableTypeNode;
import org.jruby.truffle.nodes.globals.CheckStdoutVariableTypeNode;
import org.jruby.truffle.nodes.globals.WriteReadOnlyGlobalNode;
import org.jruby.truffle.nodes.literal.*;
import org.jruby.truffle.nodes.literal.ArrayLiteralNode;
@@ -1073,6 +1074,10 @@ public RubyNode visitGlobalAsgnNode(org.jruby.ast.GlobalAsgnNode node) {

return ((ReadNode) localVarNode).makeWriteNode(rhs);
} else {
if (name.equals("$stdout")) {
rhs = new CheckStdoutVariableTypeNode(context, sourceSection, rhs);
}

final ObjectLiteralNode globalVariablesObjectNode = new ObjectLiteralNode(context, sourceSection, context.getCoreLibrary().getGlobalVariablesObject());
return new WriteInstanceVariableNode(context, sourceSection, name, globalVariablesObjectNode, rhs, true);

@@ -44,8 +44,65 @@ def Complex(real, imaginary)

end

def STDOUT.internal_encoding
nil # FIXME
# Standard file handle shims

module STDIN
def self.external_encoding
@external || Encoding.default_external
end

def self.internal_encoding
@internal
end

def self.set_encoding(external, internal)
@external = external
@internal = internal
end
end

module STDOUT
def self.print(*values)
Kernel.send(:print, *values)
end

def self.write(value)
print value
end

def self.flush
Truffle::Debug.flush_stdout
end

def self.external_encoding
@external
end

def self.internal_encoding
@internal
end

def self.set_encoding(external, internal)
@external = external
@internal = internal
end
end

$stdout = STDOUT

module STDERR
def self.external_encoding
@external
end

def self.internal_encoding
@internal
end

def self.set_encoding(external, internal)
@external = external
@internal = internal
end
end

# Here temporarily while we adapt to the newly imported specs
@@ -1,50 +1,35 @@
fails:Predefined global $~ changes the value of derived capture globals when assigned
fails:Predefined global $~ changes the value of the derived preceding match global
fails:Predefined global $~ changes the value of the derived following match global
fails:Predefined global $~ changes the value of the derived full match global
fails:Predefined global $` is equivalent to MatchData#pre_match on the last match $~
fails(inherited):Predefined global $` sets an empty result to the encoding of the source String
fails:Predefined global $' is equivalent to MatchData#post_match on the last match $~
fails(inherited):Global variable $0 raises a TypeError when not given an object that can be coerced to a String
fails(inherited):Predefined global $' sets an empty result to the encoding of the source String
fails:Predefined global $stdout raises TypeError error if assigned to nil
fails:Predefined global $stdout raises TypeError error if assigned to object that doesn't respond to #write
fails:Predefined global $! remains nil after a failed core class "checked" coercion against a class that defines method_missing
fails(inherited):Predefined global $/ changes $-0
fails:Predefined global $/ does not call #to_str to convert the object to a String
fails:Predefined global $/ raises a TypeError if assigned a Fixnum
fails:Predefined global $/ raises a TypeError if assigned a boolean
fails(inherited):Predefined global $-0 changes $/
fails(inherited):Predefined global $-0 does not call #to_str to convert the object to a String
fails(inherited):Predefined global $-0 raises a TypeError if assigned a Fixnum
fails(inherited):Predefined global $-0 raises a TypeError if assigned a boolean
fails:Predefined global $, raises TypeError if assigned a non-String
fails:Predefined global $_ is set to the last line read by e.g. StringIO#gets
fails:Predefined global $_ is set at the method-scoped level rather than block-scoped
fails(inherited):Predefined global $-0 raises a TypeError if assigned a Fixnum
fails(inherited):Predefined global $/ changes $-0
fails(inherited):Predefined global $` sets an empty result to the encoding of the source String
fails:Execution variable $: is the same object as $LOAD_PATH and $-I
fails:Global variable $-d is an alias of $DEBUG
fails:Global variable $-v is an alias of $VERBOSE
fails:Global variable $-w is an alias of $VERBOSE
fails(inherited):Global variable $0 raises a TypeError when not given an object that can be coerced to a String
fails:The predefined standard objects includes ARGF
fails:The predefined global constants includes TOPLEVEL_BINDING
fails:The predefined global constant STDERR has nil for the external encoding despite Encoding.default_external being changed
fails:The predefined global constant STDERR has the encodings set by #set_encoding
fails:The predefined global constant ARGV contains Strings encoded in locale Encoding
fails:The predefined global constant STDERR has nil for the external encoding
fails:The predefined global constant STDOUT has the encodings set by #set_encoding
fails:The predefined global constant STDOUT has nil for the external encoding despite Encoding.default_external being changed
fails:The predefined global constant STDOUT has nil for the external encoding
fails:The predefined global constant STDIN has nil for the internal encoding despite Encoding.default_internal being changed
fails:The predefined global constant STDIN has nil for the internal encoding
fails:The predefined global constant STDIN retains the encoding set by #set_encoding when Encoding.default_external is changed
fails:The predefined global constant STDIN has the encodings set by #set_encoding
fails:The predefined global constant STDIN has the same external encoding as Encoding.default_external when that encoding is changed
fails:The predefined global constant STDIN has the same external encoding as Encoding.default_external
fails:Predefined global $` sets an empty result to the encoding of the source String
fails:Global variable $0 raises a TypeError when not given an object that can be coerced to a String
fails:Predefined global $! remains nil after a failed core class "checked" coercion against a class that defines method_missing
fails:Predefined global $' is equivalent to MatchData#post_match on the last match $~
fails:Predefined global $' sets an empty result to the encoding of the source String
fails:Predefined global $/ changes $-0
fails:Predefined global $, raises TypeError if assigned a non-String
fails:Predefined global $-0 changes $/
fails:Predefined global $-0 does not call #to_str to convert the object to a String
fails:Predefined global $-0 raises a TypeError if assigned a Fixnum
fails:Predefined global $-0 raises a TypeError if assigned a boolean
fails:Global variable $0 raises a TypeError when not given an object that can be coerced to a String
fails:Predefined global $-0 raises a TypeError if assigned a Fixnum
fails:Predefined global $/ changes $-0
fails:Predefined global $/ does not call #to_str to convert the object to a String
fails:Predefined global $/ raises a TypeError if assigned a boolean
fails:Predefined global $/ raises a TypeError if assigned a Fixnum
fails:Predefined global $_ is set at the method-scoped level rather than block-scoped
fails:Predefined global $_ is set to the last line read by e.g. StringIO#gets
fails:Predefined global $` is equivalent to MatchData#pre_match on the last match $~
fails:Predefined global $` sets an empty result to the encoding of the source String
fails:Predefined global $~ changes the value of derived capture globals when assigned
fails:Predefined global $~ changes the value of the derived following match global
fails:Predefined global $~ changes the value of the derived full match global
fails:Predefined global $~ changes the value of the derived preceding match global
fails:The predefined global constants includes TOPLEVEL_BINDING
fails:The predefined standard objects includes ARGF

0 comments on commit f16b8f7

Please sign in to comment.