Skip to content

Commit

Permalink
Merge branch 'master' into truffle-head
Browse files Browse the repository at this point in the history
Conflicts:
	truffle/src/main/java/org/jruby/truffle/nodes/control/TraceNode.java
	truffle/src/main/java/org/jruby/truffle/nodes/core/ThreadBacktraceLocationNodes.java
	truffle/src/main/java/org/jruby/truffle/nodes/rubinius/TimePrimitiveNodes.java
	truffle/src/main/java/org/jruby/truffle/runtime/RubyContext.java
	truffle/src/main/java/org/jruby/truffle/runtime/backtrace/BacktraceFormatter.java
chrisseaton committed Aug 22, 2015
2 parents c33d16f + 4fd99e3 commit 08f77c6
Showing 120 changed files with 1,377 additions and 1,154 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -79,6 +79,7 @@ matrix:
fast_finish: true
allow_failures:
- env: COMMAND=test/truffle/run.sh
- env: PHASE='-Ptruffle-mri-tests'


branches:
4 changes: 3 additions & 1 deletion core/src/main/java/org/jruby/parser/ParserSupport.java
Original file line number Diff line number Diff line change
@@ -1378,7 +1378,9 @@ public String internalId() {
return "";
}

private static final String TRUFFLE_CORE_LOAD_PATH = Options.TRUFFLE_CORE_LOAD_PATH.load();

public static boolean skipTruffleRubiniusWarnings(RubyLexer lexer) {
return lexer.getFile().startsWith("core:/");
return lexer.getFile().startsWith(TRUFFLE_CORE_LOAD_PATH);
}
}
2 changes: 2 additions & 0 deletions core/src/main/java/org/jruby/util/cli/Options.java
Original file line number Diff line number Diff line change
@@ -125,6 +125,8 @@ public class Options {
public static final Option<Boolean> IR_WRITING_DEBUG = bool(IR, "ir.writing.debug", false, "Debug writing JRuby IR file.");
public static final Option<String> IR_INLINE_COMPILER_PASSES = string(IR, "ir.inline_passes", "Specify comma delimeted list of passes to run after inlining a method.");

public static final Option<String> TRUFFLE_CORE_LOAD_PATH = string(TRUFFLE, "truffle.core.load_path", "truffle:/", "Directory to load the Truffle core library from.");

public static final Option<Integer> TRUFFLE_DISPATCH_POLYMORPHIC_MAX = integer(TRUFFLE, "truffle.dispatch.polymorphic.max", 8, "Maximum size of a polymorphic call site cache.");
public static final Option<Integer> TRUFFLE_ARRAYS_UNINITIALIZED_SIZE = integer(TRUFFLE, "truffle.arrays.uninitialized_size", 32, "How large an array to allocate when we have no other information to go on.");
public static final Option<Integer> TRUFFLE_ARRAYS_SMALL = integer(TRUFFLE, "truffle.arrays.small", 3, "Maximum size of an Array to consider small for optimisations.");
1 change: 1 addition & 0 deletions spec/truffle/tags/core/argf/gets_tags.txt
Original file line number Diff line number Diff line change
@@ -2,3 +2,4 @@ fails:ARGF.gets sets $_ global variable with each line read
fails:ARGF.gets modifies the files when in place edit mode is on
fails:ARGF.gets modifies and backups two files when in place edit mode is on
slow:ARGF.gets reads all lines of stdin
fails:ARGF.gets reads all lines of stdin
3 changes: 3 additions & 0 deletions spec/truffle/tags/core/argf/read_tags.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
slow:ARGF.read reads the contents of stdin
slow:ARGF.read reads a number of bytes from stdin
slow:ARGF.read reads the contents of one file and stdin
fails:ARGF.read reads the contents of stdin
fails:ARGF.read reads a number of bytes from stdin
fails:ARGF.read reads the contents of one file and stdin
1 change: 1 addition & 0 deletions spec/truffle/tags/core/argf/readline_tags.txt
Original file line number Diff line number Diff line change
@@ -2,3 +2,4 @@ fails:ARGF.readline sets $_ global variable with each line read
fails:ARGF.readline modifies the files when in place edit mode is on
fails:ARGF.readline modifies and backups two files when in place edit mode is on
slow:ARGF.readline reads all lines of stdin
fails:ARGF.readline reads all lines of stdin
4 changes: 4 additions & 0 deletions spec/truffle/tags/core/argf/set_encoding_tags.txt
Original file line number Diff line number Diff line change
@@ -2,3 +2,7 @@ slow:ARGF.set_encoding sets the external encoding when passed an encoding instan
slow:ARGF.set_encoding sets the external encoding when passed an encoding name
slow:ARGF.set_encoding sets the external, internal encoding when passed two encoding instances
slow:ARGF.set_encoding sets the external, internal encoding when passed 'ext:int' String
fails:ARGF.set_encoding sets the external encoding when passed an encoding instance
fails:ARGF.set_encoding sets the external encoding when passed an encoding name
fails:ARGF.set_encoding sets the external, internal encoding when passed two encoding instances
fails:ARGF.set_encoding sets the external, internal encoding when passed 'ext:int' String
3 changes: 3 additions & 0 deletions spec/truffle/tags/core/encoding/default_external_tags.txt
Original file line number Diff line number Diff line change
@@ -3,3 +3,6 @@ windows:Encoding.default_external with command line options returns the encoding
slow:Encoding.default_external with command line options is not changed by the -U option
slow:Encoding.default_external with command line options returns the encoding specified by '-E external'
slow:Encoding.default_external with command line options returns the encoding specified by '-E external:'
fails:Encoding.default_external with command line options is not changed by the -U option
fails:Encoding.default_external with command line options returns the encoding specified by '-E external'
fails:Encoding.default_external with command line options returns the encoding specified by '-E external:'
3 changes: 3 additions & 0 deletions spec/truffle/tags/core/encoding/default_internal_tags.txt
Original file line number Diff line number Diff line change
@@ -4,3 +4,6 @@ windows:Encoding.default_internal with command line options uses the encoding sp
slow:Encoding.default_internal with command line options returns Encoding::UTF_8 if ruby was invoked with -U
slow:Encoding.default_internal with command line options uses the encoding specified when ruby is invoked with an '-E :internal' argument
slow:Encoding.default_internal with command line options uses the encoding specified when ruby is invoked with an '-E external:internal' argument
fails:Encoding.default_internal with command line options returns Encoding::UTF_8 if ruby was invoked with -U
fails:Encoding.default_internal with command line options uses the encoding specified when ruby is invoked with an '-E :internal' argument
fails:Encoding.default_internal with command line options uses the encoding specified when ruby is invoked with an '-E external:internal' argument
3 changes: 3 additions & 0 deletions spec/truffle/tags/core/kernel/at_exit_tags.txt
Original file line number Diff line number Diff line change
@@ -3,3 +3,6 @@ slow:Kernel.at_exit runs in reverse order of registration
slow:Kernel.at_exit allows calling exit inside at_exit handler
slow:Kernel.at_exit gives access to the last raised exception
fails:Kernel.at_exit gives access to the last raised exception
fails:Kernel.at_exit runs after all other code
fails:Kernel.at_exit runs in reverse order of registration
fails:Kernel.at_exit allows calling exit inside at_exit handler
1 change: 1 addition & 0 deletions spec/truffle/tags/core/kernel/autoload_tags.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
slow:Kernel#autoload when Object is frozen raises a RuntimeError before defining the constant
fails:Kernel#autoload when Object is frozen raises a RuntimeError before defining the constant
2 changes: 2 additions & 0 deletions spec/truffle/tags/core/kernel/caller_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:Kernel#caller returns an Array of caller locations using a custom offset
fails:Kernel#caller returns the locations as String instances
6 changes: 6 additions & 0 deletions spec/truffle/tags/core/kernel/exec_tags.txt
Original file line number Diff line number Diff line change
@@ -72,3 +72,9 @@ slow:Kernel.exec with a command array uses the first element as the command name
slow:Kernel.exec with a command array coerces the argument using to_ary
slow:Kernel.exec with a command array raises an ArgumentError if the Array does not have exactly two elements
slow:Kernel.exec with an options Hash with Integer option keys maps the key to a file descriptor in the child that inherits the file descriptor from the parent specified by the value
fails:Kernel#exec flushes STDOUT upon exit when it's not set to sync
fails:Kernel#exec flushes STDERR upon exit when it's not set to sync
fails:Kernel#exec with multiple arguments does not subject the arguments to shell expansion
fails:Kernel.exec flushes STDOUT upon exit when it's not set to sync
fails:Kernel.exec flushes STDERR upon exit when it's not set to sync
fails:Kernel.exec with multiple arguments does not subject the arguments to shell expansion
2 changes: 2 additions & 0 deletions spec/truffle/tags/core/process/exec_tags.txt
Original file line number Diff line number Diff line change
@@ -37,3 +37,5 @@ slow:Process.exec with a command array coerces the argument using to_ary
slow:Process.exec with a command array raises an ArgumentError if the Array does not have exactly two elements
slow:Process.exec with an options Hash with Integer option keys maps the key to a file descriptor in the child that inherits the file descriptor from the parent specified by the value
fails:Process.exec flushes STDOUT upon exit when it's not set to sync
fails:Process.exec with multiple arguments does not subject the arguments to shell expansion

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Thread::Backtrace::Location#inspect converts the call frame to a String
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Thread::Backtrace::Location#to_s converts the call frame to a String
1 change: 1 addition & 0 deletions spec/truffle/tags/language/predefined/data_tags.txt
Original file line number Diff line number Diff line change
@@ -10,3 +10,4 @@ windows:The DATA constant exists when the main script contains __END__
windows:The DATA constant does not exist when the main script contains no __END__
windows:The DATA constant does not change when an included files also has a __END__
fails:The DATA constant exists when the main script contains __END__
fails:The DATA constant does not exist when the main script contains no __END__
4 changes: 4 additions & 0 deletions spec/truffle/tags/language/predefined_tags.txt
Original file line number Diff line number Diff line change
@@ -10,3 +10,7 @@ windows:The predefined global constant STDERR has the encodings set by #set_enco
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:Global variable $0 actually sets the program name
fails:The predefined global constant STDIN has the encodings set by #set_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 STDOUT has the encodings set by #set_encoding
fails:The predefined global constant STDERR has the encodings set by #set_encoding
2 changes: 1 addition & 1 deletion tool/jt.rb
Original file line number Diff line number Diff line change
@@ -249,7 +249,7 @@ def rebuild

def run(*args)
env_vars = args.first.is_a?(Hash) ? args.shift : {}
jruby_args = %w[-X+T]
jruby_args = %w[-X+T -Xtruffle.core.load_path=truffle/src/main/ruby]

{ '--asm' => '--graal', '--igv' => '--graal' }.each_pair do |arg, dep|
args.unshift dep if args.include?(arg)
50 changes: 4 additions & 46 deletions truffle/src/main/java/org/jruby/truffle/nodes/RubyNode.java
Original file line number Diff line number Diff line change
@@ -23,9 +23,9 @@
import com.oracle.truffle.api.source.SourceSection;
import jnr.ffi.provider.MemoryManager;
import jnr.posix.POSIX;
import org.jcodings.Encoding;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.RubyString;
import org.jruby.truffle.nodes.core.BindingNodes;
import org.jruby.truffle.nodes.core.StringNodes;
import org.jruby.truffle.nodes.dispatch.DispatchNode;
import org.jruby.truffle.nodes.instrument.RubyWrapperNode;
import org.jruby.truffle.runtime.NotProvided;
@@ -34,9 +34,7 @@
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.truffle.runtime.sockets.NativeSockets;
import org.jruby.util.ByteList;

import java.math.BigInteger;
import java.nio.ByteBuffer;
import org.jruby.util.StringSupport;

@TypeSystemReference(RubyTypes.class)
@ImportStatic(RubyGuards.class)
@@ -62,7 +60,7 @@ public RubyNode(RubyContext context, SourceSection sourceSection) {
public abstract Object execute(VirtualFrame frame);

public Object isDefined(VirtualFrame frame) {
return StringNodes.createString(getContext().getCoreLibrary().getStringClass(), "expression");
return Layouts.STRING.createString(Layouts.CLASS.getInstanceFactory(getContext().getCoreLibrary().getStringClass()), RubyString.encodeBytelist("expression", UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
}

// Execute without returning the result
@@ -167,46 +165,6 @@ public DynamicObject getSymbol(ByteList name) {
return getContext().getSymbol(name);
}

protected DynamicObject createEmptyString() {
return StringNodes.createEmptyString(getContext().getCoreLibrary().getStringClass());
}

protected DynamicObject createString(String string) {
return StringNodes.createString(getContext().getCoreLibrary().getStringClass(), string);
}

protected DynamicObject createString(String string, Encoding encoding) {
return StringNodes.createString(getContext().getCoreLibrary().getStringClass(), string, encoding);
}

protected DynamicObject createString(byte[] bytes) {
return StringNodes.createString(getContext().getCoreLibrary().getStringClass(), bytes);
}

protected DynamicObject createString(ByteBuffer bytes) {
return StringNodes.createString(getContext().getCoreLibrary().getStringClass(), bytes);
}

protected DynamicObject createString(ByteList bytes) {
return StringNodes.createString(getContext().getCoreLibrary().getStringFactory(), bytes);
}

protected DynamicObject createEmptyArray() {
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0);
}

protected DynamicObject createArrayWith(Object... store) {
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), store, store.length);
}

protected DynamicObject createArray(Object store, int size) {
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), store, size);
}

protected DynamicObject createBignum(BigInteger value) {
return Layouts.BIGNUM.createBignum(getContext().getCoreLibrary().getBignumFactory(), value);
}

protected POSIX posix() {
return getContext().getPosix();
}
Original file line number Diff line number Diff line change
@@ -14,10 +14,10 @@
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.hash.HashNodes;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.hash.HashOperations;
import org.jruby.truffle.runtime.methods.Arity;

import java.util.Map;
@@ -68,7 +68,7 @@ public void executeVoid(VirtualFrame frame) {
}

if (!keywordsRest && keywordArguments != null) {
for (Map.Entry<Object, Object> keyValue : HashNodes.iterableKeyValues(keywordArguments)) {
for (Map.Entry<Object, Object> keyValue : HashOperations.iterableKeyValues(keywordArguments)) {
if (!keywordAllowed(keyValue.getKey().toString())) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("unknown keyword: " + keyValue.getKey().toString(), this));
Original file line number Diff line number Diff line change
@@ -17,9 +17,9 @@
import com.oracle.truffle.api.utilities.ValueProfile;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.hash.HashNodes;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.hash.HashOperations;

import java.util.Map;

@@ -76,7 +76,7 @@ public Object execute(VirtualFrame frame) {
private Object lookupKeywordInHash(DynamicObject hash) {
assert RubyGuards.isRubyHash(hash);

for (Map.Entry<Object, Object> keyValue : HashNodes.iterableKeyValues(hash)) {
for (Map.Entry<Object, Object> keyValue : HashOperations.iterableKeyValues(hash)) {
if (keyValue.getKey().toString().equals(name)) {
return keyValue.getValue();
}
Original file line number Diff line number Diff line change
@@ -15,11 +15,11 @@
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.hash.HashLiteralNode;
import org.jruby.truffle.nodes.core.hash.HashNodes;
import org.jruby.truffle.nodes.methods.MarkerNode;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.hash.BucketsStrategy;
import org.jruby.truffle.runtime.hash.HashOperations;
import org.jruby.truffle.runtime.layouts.Layouts;

import java.util.ArrayList;
@@ -63,12 +63,12 @@ private Object lookupRestKeywordArgumentHash(VirtualFrame frame) {
final DynamicObject hash = RubyArguments.getUserKeywordsHash(frame.getArguments(), minimum);

if (hash == null) {
return HashNodes.createEmptyHash(getContext().getCoreLibrary().getHashClass());
return Layouts.HASH.createHash(getContext().getCoreLibrary().getHashFactory(), null, null, null, 0, null, null, false);
}

final List<Map.Entry<Object, Object>> entries = new ArrayList<>();

outer: for (Map.Entry<Object, Object> keyValue : HashNodes.iterableKeyValues(hash)) {
outer: for (Map.Entry<Object, Object> keyValue : HashOperations.iterableKeyValues(hash)) {
for (String excludedKeyword : excludedKeywords) {
if (excludedKeyword.equals(keyValue.getKey().toString())) {
continue outer;
@@ -78,7 +78,7 @@ private Object lookupRestKeywordArgumentHash(VirtualFrame frame) {
entries.add(keyValue);
}

return BucketsStrategy.create(getContext().getCoreLibrary().getHashClass(), entries, Layouts.HASH.getCompareByIdentity(hash));
return BucketsStrategy.create(getContext(), entries, Layouts.HASH.getCompareByIdentity(hash));
}

}
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.array.ArrayUtils;
import org.jruby.truffle.runtime.layouts.Layouts;

/**
* Read the rest of arguments after a certain point into an array.
@@ -41,8 +42,6 @@ public ReadRestArgumentNode(RubyContext context, SourceSection sourceSection, in

@Override
public Object execute(VirtualFrame frame) {
final DynamicObject arrayClass = getContext().getCoreLibrary().getArrayClass();

int count = RubyArguments.getUserArgumentsCount(frame.getArguments());

int endIndex = count + negativeEndIndex;
@@ -57,19 +56,26 @@ public Object execute(VirtualFrame frame) {

final int length = endIndex - startIndex;

final Object resultStore;
final int resultLength;

if (startIndex == 0) {
final Object[] arguments = RubyArguments.extractUserArguments(frame.getArguments());
return ArrayNodes.createGeneralArray(arrayClass, arguments, length);
resultStore = arguments;
resultLength = length;
} else {
if (startIndex >= endIndex) {
noArgumentsLeftProfile.enter();
return ArrayNodes.createGeneralArray(arrayClass, null, 0);
resultStore = null;
resultLength = 0;
} else {
subsetOfArgumentsProfile.enter();
final Object[] arguments = RubyArguments.extractUserArguments(frame.getArguments());
// TODO(CS): risk here of widening types too much - always going to be Object[] - does seem to be something that does happen
return ArrayNodes.createGeneralArray(arrayClass, ArrayUtils.extractRange(arguments, startIndex, endIndex), length);
resultStore = ArrayUtils.extractRange(arguments, startIndex, endIndex);
resultLength = length;
}
}

return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), resultStore, resultLength);
}
}
Original file line number Diff line number Diff line change
@@ -17,13 +17,13 @@
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.array.ArrayNodes;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.nodes.dispatch.DispatchNode;
import org.jruby.truffle.nodes.dispatch.MissingBehavior;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.layouts.Layouts;

/*
* TODO(CS): could probably unify this with SplatCastNode with some final configuration options.
@@ -81,10 +81,10 @@ public DynamicObject castArray(DynamicObject array) {
public Object cast(Object nil) {
switch (nilBehavior) {
case EMPTY_ARRAY:
return createEmptyArray();
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0);

case ARRAY_WITH_NIL:
return ArrayNodes.createGeneralArray(getContext().getCoreLibrary().getArrayClass(), new Object[]{nil()}, 1);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), new Object[]{nil()}, 1);

case NIL:
return nil;
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.array.ArrayNodes;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.layouts.Layouts;

@NodeChild(value = "child", type = RubyNode.class)
public abstract class SingleValueCastNode extends RubyNode {
@@ -41,8 +42,7 @@ protected Object castSingle(Object[] args) {
@TruffleBoundary
@Specialization(guards = { "!noArguments(args)", "!singleArgument(args)" })
protected DynamicObject castMany(Object[] args) {
DynamicObject arrayClass = getContext().getCoreLibrary().getArrayClass();
return ArrayNodes.createGeneralArray(arrayClass, args, args.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), args, args.length);
}

protected boolean noArguments(Object[] args) {
Original file line number Diff line number Diff line change
@@ -15,17 +15,20 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.RubyString;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.array.ArrayDupNode;
import org.jruby.truffle.nodes.core.array.ArrayDupNodeGen;
import org.jruby.truffle.nodes.core.array.ArrayNodes;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.nodes.dispatch.DispatchNode;
import org.jruby.truffle.nodes.dispatch.MissingBehavior;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.util.StringSupport;

/**
* Splat as used to cast a value to an array if it isn't already, as in {@code *value}.
@@ -64,10 +67,10 @@ public SplatCastNode(RubyContext context, SourceSection sourceSection, NilBehavi
public DynamicObject splat(Object nil) {
switch (nilBehavior) {
case EMPTY_ARRAY:
return createEmptyArray();
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0);

case ARRAY_WITH_NIL:
return ArrayNodes.createGeneralArray(getContext().getCoreLibrary().getArrayClass(), new Object[]{nil()}, 1);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), new Object[]{nil()}, 1);

default: {
throw new UnsupportedOperationException();
@@ -93,23 +96,23 @@ public DynamicObject splat(VirtualFrame frame, Object object) {
}

// MRI tries to call dynamic respond_to? here.
Object respondToResult = respondToToA.call(frame, object, "respond_to?", null, createString(method), true);
Object respondToResult = respondToToA.call(frame, object, "respond_to?", null, Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(method, UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null), true);
if (respondToResult != DispatchNode.MISSING && respondToCast.executeBoolean(frame, respondToResult)) {
final Object array = toA.call(frame, object, method, null);

if (RubyGuards.isRubyArray(array)) {
return (DynamicObject) array;
} else if (array == nil() || array == DispatchNode.MISSING) {
CompilerDirectives.transferToInterpreter();
return ArrayNodes.createGeneralArray(getContext().getCoreLibrary().getArrayClass(), new Object[]{object}, 1);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), new Object[]{object}, 1);
} else {
throw new RaiseException(getContext().getCoreLibrary().typeErrorCantConvertTo(
object, getContext().getCoreLibrary().getArrayClass(), method, array, this)
);
}
}

return ArrayNodes.createGeneralArray(getContext().getCoreLibrary().getArrayClass(), new Object[]{object}, 1);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), new Object[]{object}, 1);
}

}
Original file line number Diff line number Diff line change
@@ -12,12 +12,15 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.RubyString;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.LexicalScope;
import org.jruby.truffle.runtime.RubyConstant;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.util.StringSupport;

public class ReadConstantWithLexicalScopeNode extends RubyNode implements RestartableReadConstantNode {

@@ -63,7 +66,7 @@ public Object isDefined(VirtualFrame frame) {
if (constant == null) {
return nil();
} else {
return createString("constant");
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist("constant", UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
}
}

Original file line number Diff line number Diff line change
@@ -12,12 +12,15 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.RubyString;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.literal.LiteralNode;
import org.jruby.truffle.runtime.RubyConstant;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.util.StringSupport;

public class ReadLiteralConstantNode extends RubyNode {

@@ -71,7 +74,7 @@ public Object isDefined(VirtualFrame frame) {
if (constant == null) {
return nil();
} else {
return createString("constant");
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist("constant", UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
}
}

Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
import com.oracle.truffle.api.utilities.BranchProfile;
import com.oracle.truffle.api.utilities.ConditionProfile;
import org.jcodings.specific.USASCIIEncoding;
import org.jruby.RubyString;
import org.jruby.truffle.nodes.cast.BooleanCastNode;
import org.jruby.truffle.nodes.cast.BooleanCastNodeGen;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
@@ -26,6 +27,7 @@
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.util.StringSupport;

import java.math.BigInteger;

@@ -550,7 +552,7 @@ public DynamicObject coerce(DynamicObject a, int b) {
// TODO (eregon, 16 Feb. 2015): This is NOT spec, but let's try to see if we can make it work.
// b is converted to a Bignum here in other implementations.
Object[] store = new Object[] { b, a };
return createArray(store, store.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), store, store.length);
}

@Specialization
@@ -560,15 +562,15 @@ public DynamicObject coerce(DynamicObject a, long b) {
// TODO (eregon, 16 Feb. 2015): This is NOT spec, but let's try to see if we can make it work.
// b is converted to a Bignum here in other implementations.
Object[] store = new Object[] { b, a };
return createArray(store, store.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), store, store.length);
}

@Specialization(guards = "isRubyBignum(b)")
public DynamicObject coerce(DynamicObject a, DynamicObject b) {
CompilerDirectives.transferToInterpreter();

Object[] store = new Object[] { b, a };
return createArray(store, store.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), store, store.length);
}

}
@@ -677,7 +679,7 @@ public ToSNode(RubyContext context, SourceSection sourceSection) {
@TruffleBoundary
@Specialization
public DynamicObject toS(DynamicObject value, NotProvided base) {
return createString(Layouts.BIGNUM.getValue(value).toString(), USASCIIEncoding.INSTANCE);
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(Layouts.BIGNUM.getValue(value).toString(), USASCIIEncoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
}

@TruffleBoundary
@@ -688,7 +690,7 @@ public DynamicObject toS(DynamicObject value, int base) {
throw new RaiseException(getContext().getCoreLibrary().argumentErrorInvalidRadix(base, this));
}

return createString(Layouts.BIGNUM.getValue(value).toString(base), USASCIIEncoding.INSTANCE);
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(Layouts.BIGNUM.getValue(value).toString(base), USASCIIEncoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
}

}
Original file line number Diff line number Diff line change
@@ -260,7 +260,7 @@ public LocalVariablesNode(RubyContext context, SourceSection sourceSection) {
@TruffleBoundary
@Specialization
public DynamicObject localVariables(DynamicObject binding) {
final DynamicObject array = createEmptyArray();
final DynamicObject array = Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0);

MaterializedFrame frame = Layouts.BINDING.getFrame(binding);

Original file line number Diff line number Diff line change
@@ -29,6 +29,7 @@
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.util.ByteList;
import org.jruby.util.StringSupport;
import org.jruby.util.io.EncodingUtils;

@CoreClass(name = "Encoding::Converter")
@@ -141,11 +142,11 @@ public Object transcodingMap(VirtualFrame frame) {
final TranscoderDB.Entry e = destinationEntry.value;

if (key == null) {
final Object upcased = upcaseNode.call(frame, createString(new ByteList(e.getSource())), "upcase", null);
final Object upcased = upcaseNode.call(frame, Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), new ByteList(e.getSource()), StringSupport.CR_UNKNOWN, null), "upcase", null);
key = toSymNode.call(frame, upcased, "to_sym", null);
}

final Object upcasedLookupTableKey = upcaseNode.call(frame, createString(new ByteList(e.getDestination())), "upcase", null);
final Object upcasedLookupTableKey = upcaseNode.call(frame, Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), new ByteList(e.getDestination()), StringSupport.CR_UNKNOWN, null), "upcase", null);
final Object lookupTableKey = toSymNode.call(frame, upcasedLookupTableKey, "to_sym", null);
final Object lookupTableValue = newTranscodingNode.call(frame, getContext().getCoreLibrary().getTranscodingClass(), "create", null, key, lookupTableKey);
lookupTableWriteNode.call(frame, value, "[]=", null, lookupTableKey, lookupTableValue);
Original file line number Diff line number Diff line change
@@ -18,8 +18,10 @@
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;
import org.jruby.RubyString;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.coerce.ToStrNode;
import org.jruby.truffle.nodes.coerce.ToStrNodeGen;
@@ -29,6 +31,7 @@
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.util.ByteList;
import org.jruby.util.StringSupport;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
@@ -332,7 +335,7 @@ public DynamicObject list() {

final DynamicObject[] encodings = cloneEncodingList();

return createArray(encodings, encodings.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), encodings, encodings.length);
}
}

@@ -348,7 +351,7 @@ public LocaleCharacterMapNode(RubyContext context, SourceSection sourceSection)
public DynamicObject localeCharacterMap() {
CompilerDirectives.transferToInterpreter();
final ByteList name = new ByteList(getContext().getRuntime().getEncodingService().getLocaleEncoding().getName());
return createString(name);
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), name, StringSupport.CR_UNKNOWN, null);
}
}

@@ -390,7 +393,7 @@ public Object encodingMap(VirtualFrame frame) {

final DynamicObject[] encodings = cloneEncodingList();
for (int i = 0; i < encodings.length; i++) {
final Object upcased = upcaseNode.call(frame, createString(Layouts.ENCODING.getName(encodings[i])), "upcase", null);
final Object upcased = upcaseNode.call(frame, Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), Layouts.ENCODING.getName(encodings[i]), StringSupport.CR_UNKNOWN, null), "upcase", null);
final Object key = toSymNode.call(frame, upcased, "to_sym", null);
final Object value = newTupleNode.call(frame, getContext().getCoreLibrary().getTupleClass(), "create", null, nil(), i);

@@ -402,9 +405,9 @@ public Object encodingMap(VirtualFrame frame) {
final CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<EncodingDB.Entry> e =
((CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<EncodingDB.Entry>)i.next());

final Object upcased = upcaseNode.call(frame, createString(new ByteList(e.bytes, e.p, e.end - e.p)), "upcase", null);
final Object upcased = upcaseNode.call(frame, Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), new ByteList(e.bytes, e.p, e.end - e.p), StringSupport.CR_UNKNOWN, null), "upcase", null);
final Object key = toSymNode.call(frame, upcased, "to_sym", null);
final DynamicObject alias = createString(new ByteList(e.bytes, e.p, e.end - e.p));
final DynamicObject alias = Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), new ByteList(e.bytes, e.p, e.end - e.p), StringSupport.CR_UNKNOWN, null);
final int index = e.value.getIndex();


@@ -413,19 +416,19 @@ public Object encodingMap(VirtualFrame frame) {
}

final Encoding defaultInternalEncoding = getContext().getRuntime().getDefaultInternalEncoding();
final Object internalTuple = getContext().makeTuple(frame, newTupleNode, createString("internal"), indexLookup(encodings, defaultInternalEncoding));
final Object internalTuple = getContext().makeTuple(frame, newTupleNode, Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist("internal", UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null), indexLookup(encodings, defaultInternalEncoding));
lookupTableWriteNode.call(frame, ret, "[]=", null, getSymbol("INTERNAL"), internalTuple);

final Encoding defaultExternalEncoding = getContext().getRuntime().getDefaultExternalEncoding();
final Object externalTuple = getContext().makeTuple(frame, newTupleNode, createString("external"), indexLookup(encodings, defaultExternalEncoding));
final Object externalTuple = getContext().makeTuple(frame, newTupleNode, Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist("external", UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null), indexLookup(encodings, defaultExternalEncoding));
lookupTableWriteNode.call(frame, ret, "[]=", null, getSymbol("EXTERNAL"), externalTuple);

final Encoding localeEncoding = getLocaleEncoding();
final Object localeTuple = getContext().makeTuple(frame, newTupleNode, createString("locale"), indexLookup(encodings, localeEncoding));
final Object localeTuple = getContext().makeTuple(frame, newTupleNode, Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist("locale", UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null), indexLookup(encodings, localeEncoding));
lookupTableWriteNode.call(frame, ret, "[]=", null, getSymbol("LOCALE"), localeTuple);

final Encoding filesystemEncoding = getLocaleEncoding();
final Object filesystemTuple = getContext().makeTuple(frame, newTupleNode, createString("filesystem"), indexLookup(encodings, filesystemEncoding));
final Object filesystemTuple = getContext().makeTuple(frame, newTupleNode, Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist("filesystem", UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null), indexLookup(encodings, filesystemEncoding));
lookupTableWriteNode.call(frame, ret, "[]=", null, getSymbol("FILESYSTEM"), filesystemTuple);

return ret;
@@ -465,7 +468,7 @@ public ToSNode(RubyContext context, SourceSection sourceSection) {
public DynamicObject toS(DynamicObject encoding) {
final ByteList name = Layouts.ENCODING.getName(encoding).dup();
name.setEncoding(ASCIIEncoding.INSTANCE);
return createString(name);
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), name, StringSupport.CR_UNKNOWN, null);
}
}

Original file line number Diff line number Diff line change
@@ -13,15 +13,17 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.RubyString;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.core.array.ArrayNodes;
import org.jruby.truffle.nodes.objectstorage.ReadHeadObjectFieldNode;
import org.jruby.truffle.runtime.NotProvided;
import org.jruby.truffle.runtime.RubyCallStack;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.backtrace.Backtrace;
import org.jruby.truffle.runtime.backtrace.BacktraceFormatter;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.util.StringSupport;

import java.util.EnumSet;
import java.util.List;
@@ -42,11 +44,10 @@ public static DynamicObject asRubyStringArray(DynamicObject exception) {
final Object[] array = new Object[lines.size()];

for (int n = 0;n < lines.size(); n++) {
array[n] = StringNodes.createString(Layouts.MODULE.getFields(Layouts.BASIC_OBJECT.getLogicalClass(exception)).getContext().getCoreLibrary().getStringClass(), lines.get(n));
array[n] = Layouts.STRING.createString(Layouts.CLASS.getInstanceFactory(Layouts.MODULE.getFields(Layouts.BASIC_OBJECT.getLogicalClass(exception)).getContext().getCoreLibrary().getStringClass()), RubyString.encodeBytelist(lines.get(n), UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
}

DynamicObject arrayClass = Layouts.MODULE.getFields(Layouts.BASIC_OBJECT.getLogicalClass(exception)).getContext().getCoreLibrary().getArrayClass();
return ArrayNodes.createGeneralArray(arrayClass, array, array.length);
return Layouts.ARRAY.createArray(Layouts.MODULE.getFields(Layouts.BASIC_OBJECT.getLogicalClass(exception)).getContext().getCoreLibrary().getArrayFactory(), array, array.length);
}

public static void setMessage(DynamicObject exception, Object message) {
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@
import com.oracle.truffle.api.utilities.BranchProfile;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.layouts.Layouts;

import java.math.BigDecimal;
import java.math.BigInteger;
@@ -53,7 +54,7 @@ public Object fixnumOrBignum(BigInteger value) {
return longValue;
}
} else {
return createBignum(value);
return Layouts.BIGNUM.createBignum(getContext().getCoreLibrary().getBignumFactory(), value);
}
}

Original file line number Diff line number Diff line change
@@ -18,12 +18,14 @@
import com.oracle.truffle.api.utilities.BranchProfile;
import com.oracle.truffle.api.utilities.ConditionProfile;
import org.jcodings.specific.USASCIIEncoding;
import org.jruby.RubyString;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.runtime.NotProvided;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.util.StringSupport;

@CoreClass(name = "Float")
public abstract class FloatNodes {
@@ -699,7 +701,7 @@ public ToSNode(RubyContext context, SourceSection sourceSection) {
@TruffleBoundary
@Specialization
public DynamicObject toS(double value) {
return createString(Double.toString(value), USASCIIEncoding.INSTANCE);
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(Double.toString(value), USASCIIEncoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
}

}
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.layouts.Layouts;

import java.math.BigInteger;

@@ -106,15 +107,15 @@ private DynamicObject divMod(long a, long b) {

if (integerDiv instanceof Long && ((long) integerDiv) >= Integer.MIN_VALUE && ((long) integerDiv) <= Integer.MAX_VALUE && mod >= Integer.MIN_VALUE && mod <= Integer.MAX_VALUE) {
useFixnumPairProfile.enter();
return createArray(new int[]{(int) (long) integerDiv, (int) mod}, 2);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), new int[]{(int) (long) integerDiv, (int) mod}, 2);
} else if (integerDiv instanceof Long) {
useObjectPairProfile.enter();
return createArray(new Object[]{integerDiv, mod}, 2);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), new Object[]{integerDiv, mod}, 2);
} else {
useObjectPairProfile.enter();
return createArray(new Object[]{
fixnumOrBignumQuotient.fixnumOrBignum((BigInteger) integerDiv),
mod}, 2);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), new Object[]{
fixnumOrBignumQuotient.fixnumOrBignum((BigInteger) integerDiv),
mod}, 2);
}
}

@@ -138,7 +139,7 @@ private DynamicObject divMod(double a, double b) {
mod += b;
}

return createArray(new Object[]{
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), new Object[]{
fixnumOrBignumQuotient.fixnumOrBignum(div),
mod}, 2);
}
@@ -158,7 +159,7 @@ private DynamicObject divMod(BigInteger a, BigInteger b) {
bigIntegerResults[1] = b.add(bigIntegerResults[1]);
}

return createArray(new Object[]{
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), new Object[]{
fixnumOrBignumQuotient.fixnumOrBignum(bigIntegerResults[0]),
fixnumOrBignumRemainder.fixnumOrBignum(bigIntegerResults[1])}, 2);
}
Original file line number Diff line number Diff line change
@@ -100,7 +100,7 @@ public DynamicObject times(VirtualFrame frame, int n, NotProvided block) {
array[i] = i;
}

return createArray(array, n);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), array, n);
}

@Specialization(guards = "isRubyProc(block)")
65 changes: 27 additions & 38 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/KernelNodes.java
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@
import org.jcodings.Encoding;
import org.jcodings.specific.USASCIIEncoding;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.RubyString;
import org.jruby.exceptions.MainExitException;
import org.jruby.runtime.Visibility;
import org.jruby.truffle.nodes.RubyGuards;
@@ -45,8 +46,6 @@
import org.jruby.truffle.nodes.core.KernelNodesFactory.SingletonMethodsNodeFactory;
import org.jruby.truffle.nodes.core.ProcNodes.ProcNewNode;
import org.jruby.truffle.nodes.core.ProcNodesFactory.ProcNewNodeFactory;
import org.jruby.truffle.nodes.core.array.ArrayNodes;
import org.jruby.truffle.nodes.core.hash.HashNodes;
import org.jruby.truffle.nodes.dispatch.*;
import org.jruby.truffle.nodes.methods.LookupMethodNode;
import org.jruby.truffle.nodes.methods.LookupMethodNodeGen;
@@ -64,13 +63,15 @@
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.ArrayOperations;
import org.jruby.truffle.runtime.core.MethodFilter;
import org.jruby.truffle.runtime.hash.HashOperations;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.truffle.runtime.methods.InternalMethod;
import org.jruby.truffle.runtime.subsystems.FeatureManager;
import org.jruby.truffle.runtime.loader.FeatureLoader;
import org.jruby.truffle.runtime.subsystems.ThreadManager.BlockingAction;
import org.jruby.truffle.translator.NodeWrapper;
import org.jruby.truffle.translator.TranslatorDriver;
import org.jruby.util.ByteList;
import org.jruby.util.StringSupport;

import java.io.BufferedReader;
import java.io.IOException;
@@ -113,7 +114,7 @@ public DynamicObject backtick(VirtualFrame frame, DynamicObject command) {
final List<String> envp = new ArrayList<>();

// TODO(CS): cast
for (Map.Entry<Object, Object> keyValue : HashNodes.iterableKeyValues(envAsHash)) {
for (Map.Entry<Object, Object> keyValue : HashOperations.iterableKeyValues(envAsHash)) {
envp.add(keyValue.getKey().toString() + "=" + keyValue.getValue().toString());
}

@@ -144,7 +145,7 @@ public DynamicObject backtick(VirtualFrame frame, DynamicObject command) {
}

// TODO (nirvdrum 10-Mar-15) This should be using the default external encoding, rather than hard-coded to UTF-8.
return createString(resultBuilder.toString(), Layouts.ENCODING.getEncoding(EncodingNodes.getEncoding("UTF-8")));
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(resultBuilder.toString(), Layouts.ENCODING.getEncoding(EncodingNodes.getEncoding("UTF-8"))), StringSupport.CR_UNKNOWN, null);
}

}
@@ -361,7 +362,7 @@ public DynamicObject callerLocations(int omit, int length) {
locations[n] = ThreadBacktraceLocationNodes.createRubyThreadBacktraceLocation(threadBacktraceLocationClass, activation);
}

return createArray(locations, locations.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), locations, locations.length);
}
}

@@ -685,7 +686,7 @@ private static void exec(RubyContext context, DynamicObject envAsHash, String[]
final ProcessBuilder builder = new ProcessBuilder(commandLine);
builder.inheritIO();

for (Map.Entry<Object, Object> keyValue : HashNodes.iterableKeyValues(envAsHash)) {
for (Map.Entry<Object, Object> keyValue : HashOperations.iterableKeyValues(envAsHash)) {
builder.environment().put(keyValue.getKey().toString(), keyValue.getValue().toString());
}

@@ -846,7 +847,7 @@ public String block() throws InterruptedException {
}
});

final DynamicObject rubyLine = createString(line);
final DynamicObject rubyLine = Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(line, UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null);

// Set the local variable $_ in the caller

@@ -1053,7 +1054,7 @@ public DynamicObject instanceVariables(DynamicObject self) {

Arrays.sort(instanceVariableNames);

final DynamicObject array = createEmptyArray();
final DynamicObject array = Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0);

for (Object name : instanceVariableNames) {
if (name instanceof String) {
@@ -1173,15 +1174,8 @@ public boolean load(DynamicObject file, boolean wrap) {

try {
getContext().loadFile(file.toString(), this);
} catch (RuntimeException e) {
// TODO (nirvdrum 05-Feb-15) This is ugly, but checked exceptions are wrapped up the call stack. We need to revisit this.
if (e.getCause() instanceof java.io.IOException) {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(getContext().getCoreLibrary().loadErrorCannotLoad(file.toString(), this));
} else {
throw e;
}
} catch (IOException e) {
throw new RaiseException(getContext().getCoreLibrary().loadErrorCannotLoad(file.toString(), this));
}

return true;
@@ -1204,7 +1198,7 @@ public LocalVariablesNode(RubyContext context, SourceSection sourceSection) {
public DynamicObject localVariables() {
CompilerDirectives.transferToInterpreter();

final DynamicObject array = createEmptyArray();
final DynamicObject array = Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0);

for (Object name : RubyCallStack.getCallerFrame(getContext()).getFrame(FrameInstance.FrameAccess.READ_ONLY, false).getFrameDescriptor().getIdentifiers()) {
if (name instanceof String) {
@@ -1289,9 +1283,8 @@ public DynamicObject methodsRegular(VirtualFrame frame, Object self, boolean reg
final DynamicObject metaClass = metaClassNode.executeMetaClass(frame, self);

CompilerDirectives.transferToInterpreter();
DynamicObject arrayClass = getContext().getCoreLibrary().getArrayClass();
Object[] objects = Layouts.MODULE.getFields(metaClass).filterMethodsOnObject(regular, MethodFilter.PUBLIC_PROTECTED).toArray();
return ArrayNodes.createGeneralArray(arrayClass, objects, objects.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), objects, objects.length);
}

@Specialization(guards = "!regular")
@@ -1347,9 +1340,8 @@ public DynamicObject privateMethods(VirtualFrame frame, Object self, boolean inc
DynamicObject metaClass = metaClassNode.executeMetaClass(frame, self);

CompilerDirectives.transferToInterpreter();
DynamicObject arrayClass = getContext().getCoreLibrary().getArrayClass();
Object[] objects = Layouts.MODULE.getFields(metaClass).filterMethodsOnObject(includeAncestors, MethodFilter.PRIVATE).toArray();
return ArrayNodes.createGeneralArray(arrayClass, objects, objects.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), objects, objects.length);
}

}
@@ -1395,9 +1387,8 @@ public DynamicObject protectedMethods(VirtualFrame frame, Object self, boolean i
final DynamicObject metaClass = metaClassNode.executeMetaClass(frame, self);

CompilerDirectives.transferToInterpreter();
DynamicObject arrayClass = getContext().getCoreLibrary().getArrayClass();
Object[] objects = Layouts.MODULE.getFields(metaClass).filterMethodsOnObject(includeAncestors, MethodFilter.PROTECTED).toArray();
return ArrayNodes.createGeneralArray(arrayClass, objects, objects.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), objects, objects.length);
}

}
@@ -1426,9 +1417,8 @@ public DynamicObject publicMethods(VirtualFrame frame, Object self, boolean incl
final DynamicObject metaClass = metaClassNode.executeMetaClass(frame, self);

CompilerDirectives.transferToInterpreter();
DynamicObject arrayClass = getContext().getCoreLibrary().getArrayClass();
Object[] objects = Layouts.MODULE.getFields(metaClass).filterMethodsOnObject(includeAncestors, MethodFilter.PUBLIC).toArray();
return ArrayNodes.createGeneralArray(arrayClass, objects, objects.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), objects, objects.length);
}

}
@@ -1548,7 +1538,7 @@ public boolean require(DynamicObject featureString) {
}

try {
getContext().getFeatureManager().require(feature, this);
getContext().getFeatureLoader().require(feature, this);
} catch (IOException e) {
throw new RuntimeException(e);
}
@@ -1567,16 +1557,16 @@ public RequireRelativeNode(RubyContext context, SourceSection sourceSection) {
@TruffleBoundary
@Specialization(guards = "isRubyString(feature)")
public boolean requireRelative(DynamicObject feature) {
final FeatureManager featureManager = getContext().getFeatureManager();
final FeatureLoader featureLoader = getContext().getFeatureLoader();

final String featureString = feature.toString();
final String featurePath;

if (featureManager.isAbsolutePath(featureString)) {
if (featureLoader.isAbsolutePath(featureString)) {
featurePath = featureString;
} else {
final Source source = RubyCallStack.getCallerFrame(getContext()).getCallNode().getEncapsulatingSourceSection().getSource();
final String sourcePath = featureManager.getSourcePath(source);
final String sourcePath = featureLoader.getSourcePath(source);

if (sourcePath == null) {
CompilerDirectives.transferToInterpreter();
@@ -1587,7 +1577,7 @@ public boolean requireRelative(DynamicObject feature) {
}

try {
featureManager.require(featurePath, this);
featureLoader.require(featurePath, this);
} catch (IOException e) {
throw new RuntimeException(e);
}
@@ -1764,13 +1754,12 @@ public DynamicObject singletonMethods(VirtualFrame frame, Object self, boolean i
final DynamicObject metaClass = metaClassNode.executeMetaClass(frame, self);

if (!Layouts.CLASS.getIsSingleton(metaClass)) {
return createEmptyArray();
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0);
}

CompilerDirectives.transferToInterpreter();
DynamicObject arrayClass = getContext().getCoreLibrary().getArrayClass();
Object[] objects = Layouts.MODULE.getFields(metaClass).filterSingletonMethods(includeAncestors, MethodFilter.PUBLIC_PROTECTED).toArray();
return ArrayNodes.createGeneralArray(arrayClass, objects, objects.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), objects, objects.length);
}

}
@@ -1948,7 +1937,7 @@ private RuntimeException handleException(PackException exception) {
}

private DynamicObject finishFormat(ByteList format, PackResult result) {
final DynamicObject string = createString(new ByteList(result.getOutput(), 0, result.getOutputLength()));
final DynamicObject string = Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), new ByteList(result.getOutput(), 0, result.getOutputLength()), StringSupport.CR_UNKNOWN, null);

if (format.length() == 0) {
StringNodes.forceEncoding(string, USASCIIEncoding.INSTANCE);
@@ -2020,7 +2009,7 @@ public boolean system(VirtualFrame frame, DynamicObject command) {
final List<String> envp = new ArrayList<>();

// TODO(CS): cast
for (Map.Entry<Object, Object> keyValue : HashNodes.iterableKeyValues(envAsHash)) {
for (Map.Entry<Object, Object> keyValue : HashOperations.iterableKeyValues(envAsHash)) {
envp.add(keyValue.getKey().toString() + "=" + keyValue.getValue().toString());
}

@@ -2125,7 +2114,7 @@ public DynamicObject toS(VirtualFrame frame, Object self) {
Object id = objectIDNode.executeObjectID(frame, self);
String hexID = toHexStringNode.executeToHexString(frame, id);

return createString("#<" + className + ":0x" + hexID + ">");
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist("#<" + className + ":0x" + hexID + ">", UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
}

}
Original file line number Diff line number Diff line change
@@ -11,11 +11,15 @@

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.RubyString;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.util.StringSupport;

import java.util.Collection;

@@ -35,7 +39,7 @@ public Object execute(VirtualFrame frame) {
Collection<String> requiredLibraries = getContext().getRuntime().getInstanceConfig().getRequiredLibraries();

for (String requiredLibrary : requiredLibraries) {
requireNode.call(frame, self, "require", null, createString(requiredLibrary));
requireNode.call(frame, self, "require", null, Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(requiredLibrary, UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null));
}

return nil();
Original file line number Diff line number Diff line change
@@ -24,7 +24,6 @@
import org.jruby.truffle.nodes.cast.TaintResultNode;
import org.jruby.truffle.nodes.coerce.ToIntNode;
import org.jruby.truffle.nodes.coerce.ToIntNodeGen;
import org.jruby.truffle.nodes.core.array.ArrayNodes;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.runtime.NotProvided;
@@ -225,7 +224,7 @@ public Object getIndex(DynamicObject matchData, int index, int length) {
final Object[] values = Arrays.copyOf(Layouts.MATCH_DATA.getValues(matchData), Layouts.MATCH_DATA.getValues(matchData).length);
final int normalizedIndex = ArrayOperations.normalizeIndex(values.length, index);
final Object[] store = Arrays.copyOfRange(values, normalizedIndex, normalizedIndex + length);
return createArray(store, length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), store, length);
}

@Specialization(guards = "isRubySymbol(index)")
@@ -284,7 +283,7 @@ public Object getIndex(DynamicObject matchData, DynamicObject range, NotProvided
final int length = exclusiveEnd - normalizedIndex;

final Object[] store = Arrays.copyOfRange(values, normalizedIndex, normalizedIndex + length);
return createArray(store, length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), store, length);
}

}
@@ -326,9 +325,8 @@ public CapturesNode(RubyContext context, SourceSection sourceSection) {
public DynamicObject toA(DynamicObject matchData) {
CompilerDirectives.transferToInterpreter();

DynamicObject arrayClass = getContext().getCoreLibrary().getArrayClass();
Object[] objects = getCaptures(matchData);
return ArrayNodes.createGeneralArray(arrayClass, objects, objects.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), objects, objects.length);
}
}

@@ -448,9 +446,8 @@ public ToANode(RubyContext context, SourceSection sourceSection) {
public DynamicObject toA(DynamicObject matchData) {
CompilerDirectives.transferToInterpreter();

DynamicObject arrayClass = getContext().getCoreLibrary().getArrayClass();
Object[] objects = Arrays.copyOf(Layouts.MATCH_DATA.getValues(matchData), Layouts.MATCH_DATA.getValues(matchData).length);
return ArrayNodes.createGeneralArray(arrayClass, objects, objects.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), objects, objects.length);
}
}

@@ -466,7 +463,7 @@ public DynamicObject toS(DynamicObject matchData) {
CompilerDirectives.transferToInterpreter();

final ByteList bytes = Layouts.STRING.getByteList(Layouts.MATCH_DATA.getGlobal(matchData)).dup();
return createString(bytes);
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), bytes, StringSupport.CR_UNKNOWN, null);
}
}

Original file line number Diff line number Diff line change
@@ -358,7 +358,7 @@ public DynamicObject frexp(double a) {
for (; mantissa >= 1.0; mantissa *= 0.5, exponent +=1) { }
}

return createArray(new Object[]{sign * mantissa, exponent}, 2);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), new Object[]{sign * mantissa, exponent}, 2);
}

@Fallback
@@ -577,7 +577,7 @@ public DynamicObject lgamma(double a) {

final RubyMath.NemesLogGamma l = new RubyMath.NemesLogGamma(a);

return createArray(new Object[]{l.value, l.sign}, 2);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), new Object[]{l.value, l.sign}, 2);
}

@Fallback
Original file line number Diff line number Diff line change
@@ -21,6 +21,8 @@
import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.RubyString;
import org.jruby.ast.ArgsNode;
import org.jruby.runtime.ArgumentDescriptor;
import org.jruby.runtime.Helpers;
@@ -29,7 +31,6 @@
import org.jruby.truffle.nodes.cast.ProcOrNullNode;
import org.jruby.truffle.nodes.cast.ProcOrNullNodeGen;
import org.jruby.truffle.nodes.core.BasicObjectNodes.ReferenceEqualNode;
import org.jruby.truffle.nodes.core.array.ArrayNodes;
import org.jruby.truffle.nodes.methods.CallMethodNode;
import org.jruby.truffle.nodes.methods.CallMethodNodeGen;
import org.jruby.truffle.nodes.objects.ClassNode;
@@ -38,6 +39,7 @@
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.truffle.runtime.methods.InternalMethod;
import org.jruby.util.StringSupport;

@CoreClass(name = "Method")
public abstract class MethodNodes {
@@ -200,10 +202,9 @@ public Object sourceLocation(DynamicObject method) {
if (sourceSection.getSource() == null) {
return nil();
} else {
DynamicObject file = createString(sourceSection.getSource().getName());
DynamicObject arrayClass = getContext().getCoreLibrary().getArrayClass();
DynamicObject file = Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(sourceSection.getSource().getName(), UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
Object[] objects = new Object[]{file, sourceSection.getStartLine()};
return ArrayNodes.createGeneralArray(arrayClass, objects, objects.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), objects, objects.length);
}
}

34 changes: 14 additions & 20 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/ModuleNodes.java
Original file line number Diff line number Diff line change
@@ -22,6 +22,8 @@
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.ConditionProfile;
import org.jcodings.Encoding;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.RubyString;
import org.jruby.runtime.Visibility;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
@@ -39,7 +41,6 @@
import org.jruby.truffle.nodes.core.ModuleNodesFactory.GenerateAccessorNodeGen;
import org.jruby.truffle.nodes.core.ModuleNodesFactory.SetMethodVisibilityNodeGen;
import org.jruby.truffle.nodes.core.ModuleNodesFactory.SetVisibilityNodeGen;
import org.jruby.truffle.nodes.core.array.ArrayNodes;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.nodes.methods.AddMethodNode;
@@ -60,6 +61,7 @@
import org.jruby.truffle.translator.NodeWrapper;
import org.jruby.truffle.translator.TranslatorDriver;
import org.jruby.util.IdUtil;
import org.jruby.util.StringSupport;

import java.util.ArrayList;
import java.util.List;
@@ -348,9 +350,8 @@ public DynamicObject ancestors(DynamicObject self) {
ancestors.add(module);
}

DynamicObject arrayClass = getContext().getCoreLibrary().getArrayClass();
Object[] objects = ancestors.toArray(new Object[ancestors.size()]);
return ArrayNodes.createGeneralArray(arrayClass, objects, objects.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), objects, objects.length);
}
}

@@ -803,7 +804,7 @@ public ClassVariablesNode(RubyContext context, SourceSection sourceSection) {
public DynamicObject getClassVariables(DynamicObject module) {
CompilerDirectives.transferToInterpreter();

final DynamicObject array = ArrayNodes.createGeneralArray(Layouts.MODULE.getFields(Layouts.BASIC_OBJECT.getLogicalClass(module)).getContext().getCoreLibrary().getArrayClass(), null, 0);
final DynamicObject array = Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0);

for (String variable : ModuleOperations.getAllClassVariables(module).keySet()) {
ArrayOperations.append(array, getSymbol(variable));
@@ -847,9 +848,8 @@ public DynamicObject constants(DynamicObject module, boolean inherit) {
}
}

DynamicObject arrayClass = getContext().getCoreLibrary().getArrayClass();
Object[] objects = constantsArray.toArray(new Object[constantsArray.size()]);
return ArrayNodes.createGeneralArray(arrayClass, objects, objects.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), objects, objects.length);
}

}
@@ -1245,9 +1245,8 @@ public DynamicObject includedModules(DynamicObject module) {
}
}

DynamicObject arrayClass = getContext().getCoreLibrary().getArrayClass();
Object[] objects = modules.toArray(new Object[modules.size()]);
return ArrayNodes.createGeneralArray(arrayClass, objects, objects.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), objects, objects.length);
}
}

@@ -1325,7 +1324,7 @@ public Object name(DynamicObject module) {
return nil();
}

return createString(Layouts.MODULE.getFields(module).getName());
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(Layouts.MODULE.getFields(module).getName(), UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
}
}

@@ -1354,9 +1353,8 @@ public DynamicObject nesting() {
lexicalScope = lexicalScope.getParent();
}

DynamicObject arrayClass = getContext().getCoreLibrary().getArrayClass();
Object[] objects = modules.toArray(new Object[modules.size()]);
return ArrayNodes.createGeneralArray(arrayClass, objects, objects.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), objects, objects.length);
}
}

@@ -1511,9 +1509,8 @@ public RubyNode coerceToBoolean(RubyNode includeAncestors) {
@Specialization
public DynamicObject protectedInstanceMethods(DynamicObject module, boolean includeAncestors) {
CompilerDirectives.transferToInterpreter();
DynamicObject arrayClass = getContext().getCoreLibrary().getArrayClass();
Object[] objects = Layouts.MODULE.getFields(module).filterMethods(includeAncestors, MethodFilter.PROTECTED).toArray();
return ArrayNodes.createGeneralArray(arrayClass, objects, objects.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), objects, objects.length);
}
}

@@ -1561,9 +1558,8 @@ public RubyNode coerceToBoolean(RubyNode includeAncestors) {
public DynamicObject privateInstanceMethods(DynamicObject module, boolean includeAncestors) {
CompilerDirectives.transferToInterpreter();

DynamicObject arrayClass = getContext().getCoreLibrary().getArrayClass();
Object[] objects = Layouts.MODULE.getFields(module).filterMethods(includeAncestors, MethodFilter.PRIVATE).toArray();
return ArrayNodes.createGeneralArray(arrayClass, objects, objects.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), objects, objects.length);
}
}

@@ -1621,9 +1617,8 @@ public RubyNode coerceToBoolean(RubyNode includeAncestors) {
public DynamicObject publicInstanceMethods(DynamicObject module, boolean includeAncestors) {
CompilerDirectives.transferToInterpreter();

DynamicObject arrayClass = getContext().getCoreLibrary().getArrayClass();
Object[] objects = Layouts.MODULE.getFields(module).filterMethods(includeAncestors, MethodFilter.PUBLIC).toArray();
return ArrayNodes.createGeneralArray(arrayClass, objects, objects.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), objects, objects.length);
}
}

@@ -1671,9 +1666,8 @@ public RubyNode coerceToBoolean(RubyNode includeAncestors) {
public DynamicObject instanceMethods(DynamicObject module, boolean includeAncestors) {
CompilerDirectives.transferToInterpreter();

DynamicObject arrayClass = getContext().getCoreLibrary().getArrayClass();
Object[] objects = Layouts.MODULE.getFields(module).filterMethods(includeAncestors, MethodFilter.PUBLIC_PROTECTED).toArray();
return ArrayNodes.createGeneralArray(arrayClass, objects, objects.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), objects, objects.length);
}
}

@@ -1867,7 +1861,7 @@ public ToSNode(RubyContext context, SourceSection sourceSection) {
public DynamicObject toS(DynamicObject module) {
CompilerDirectives.transferToInterpreter();

return createString(Layouts.MODULE.getFields(module).getName());
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(Layouts.MODULE.getFields(module).getName(), UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
}

}
Original file line number Diff line number Diff line change
@@ -16,7 +16,6 @@
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.core.array.ArrayNodes;
import org.jruby.truffle.nodes.dispatch.RespondToNode;
import org.jruby.truffle.runtime.ModuleOperations;
import org.jruby.truffle.runtime.NotProvided;
@@ -155,9 +154,8 @@ public DefineFinalizerNode(RubyContext context, SourceSection sourceSection) {
public DynamicObject defineFinalizer(VirtualFrame frame, Object object, Object finalizer) {
if (respondToNode.executeBoolean(frame, finalizer)) {
registerFinalizer(object, finalizer);
DynamicObject arrayClass = getContext().getCoreLibrary().getArrayClass();
Object[] objects = new Object[]{0, finalizer};
return ArrayNodes.createGeneralArray(arrayClass, objects, objects.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), objects, objects.length);
} else {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentErrorWrongArgumentType(finalizer, "callable", this));
Original file line number Diff line number Diff line change
@@ -20,11 +20,12 @@
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.object.DynamicObjectFactory;
import com.oracle.truffle.api.source.SourceSection;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.RubyString;
import org.jruby.ast.ArgsNode;
import org.jruby.runtime.ArgumentDescriptor;
import org.jruby.runtime.Helpers;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.core.array.ArrayNodes;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.nodes.yield.YieldDispatchHeadNode;
@@ -36,6 +37,7 @@
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.truffle.runtime.methods.InternalMethod;
import org.jruby.truffle.runtime.methods.SharedMethodInfo;
import org.jruby.util.StringSupport;

@CoreClass(name = "Proc")
public abstract class ProcNodes {
@@ -267,10 +269,9 @@ public Object sourceLocation(DynamicObject proc) {
if (sourceSection.getSource() == null) {
return nil();
} else {
DynamicObject file = createString(sourceSection.getSource().getName());
DynamicObject arrayClass = getContext().getCoreLibrary().getArrayClass();
DynamicObject file = Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(sourceSection.getSource().getName(), UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
Object[] objects = new Object[]{file, sourceSection.getStartLine()};
return ArrayNodes.createGeneralArray(arrayClass, objects, objects.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), objects, objects.length);
}
}

Original file line number Diff line number Diff line change
@@ -390,15 +390,15 @@ public DynamicObject toA(DynamicObject range) {
final int length = result - begin;

if (length < 0) {
return createEmptyArray();
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0);
} else {
final int[] values = new int[length];

for (int n = 0; n < length; n++) {
values[n] = begin + n;
}

return createArray(values, length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), values, length);
}
}

28 changes: 15 additions & 13 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/RegexpNodes.java
Original file line number Diff line number Diff line change
@@ -23,14 +23,15 @@
import org.jcodings.Encoding;
import org.jcodings.specific.ASCIIEncoding;
import org.jcodings.specific.USASCIIEncoding;
import org.jcodings.specific.UTF8Encoding;
import org.joni.*;
import org.joni.exception.SyntaxException;
import org.joni.exception.ValueException;
import org.jruby.RubyString;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.coerce.ToStrNode;
import org.jruby.truffle.nodes.coerce.ToStrNodeGen;
import org.jruby.truffle.nodes.core.array.ArrayNodes;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.runtime.RubyArguments;
@@ -49,11 +50,12 @@
@CoreClass(name = "Regexp")
public abstract class RegexpNodes {

@TruffleBoundary
public static DynamicObject makeString(DynamicObject source, int start, int length) {
assert RubyGuards.isRubyString(source);

final ByteList bytes = new ByteList(Layouts.STRING.getByteList(source), start, length);
final DynamicObject ret = StringNodes.createString(Layouts.BASIC_OBJECT.getLogicalClass(source), bytes);
final DynamicObject ret = Layouts.STRING.createString(Layouts.CLASS.getInstanceFactory(Layouts.BASIC_OBJECT.getLogicalClass(source)), bytes, StringSupport.CR_UNKNOWN, null);

Layouts.STRING.setCodeRange(ret, Layouts.STRING.getCodeRange(source));

@@ -254,7 +256,7 @@ public static DynamicObject gsub(DynamicObject regexp, DynamicObject string, Str
end = StringSupport.positionEndForScan(Layouts.STRING.getByteList(string), matcher, encoding, p, range);
}

return StringNodes.createString(context.getCoreLibrary().getStringClass(), builder.toString());
return Layouts.STRING.createString(Layouts.CLASS.getInstanceFactory(context.getCoreLibrary().getStringClass()), RubyString.encodeBytelist(builder.toString(), UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
}

@TruffleBoundary
@@ -286,12 +288,12 @@ public static DynamicObject[] split(DynamicObject regexp, final DynamicObject st
while ((end = matcher.search(start, range, Option.NONE)) >= 0) {
if (start == end + begin && matcher.getBegin() == matcher.getEnd()) {
if (len == 0) {
strings.add(StringNodes.createString(context.getCoreLibrary().getStringClass(), ""));
strings.add(Layouts.STRING.createString(Layouts.CLASS.getInstanceFactory(context.getCoreLibrary().getStringClass()), RubyString.encodeBytelist("", UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null));
break;

} else if (lastNull) {
final int substringLength = StringSupport.length(encoding, byteArray, begin + beg, range);
strings.add(StringNodes.createString(context.getCoreLibrary().getStringClass(), bytes.makeShared(beg, substringLength).dup()));
strings.add(Layouts.STRING.createString(context.getCoreLibrary().getStringFactory(), bytes.makeShared(beg, substringLength).dup(), StringSupport.CR_UNKNOWN, null));
beg = start - begin;

} else {
@@ -300,7 +302,7 @@ public static DynamicObject[] split(DynamicObject regexp, final DynamicObject st
continue;
}
} else {
strings.add(StringNodes.createString(context.getCoreLibrary().getStringClass(), bytes.makeShared(beg, end - beg).dup()));
strings.add(Layouts.STRING.createString(context.getCoreLibrary().getStringFactory(), bytes.makeShared(beg, end - beg).dup(), StringSupport.CR_UNKNOWN, null));
beg = matcher.getEnd();
start = begin + beg;
}
@@ -311,7 +313,7 @@ public static DynamicObject[] split(DynamicObject regexp, final DynamicObject st
}

if (len > 0 && (useLimit || len > beg || limit < 0)) {
strings.add(StringNodes.createString(context.getCoreLibrary().getStringClass(), bytes.makeShared(beg, len - beg).dup()));
strings.add(Layouts.STRING.createString(context.getCoreLibrary().getStringFactory(), bytes.makeShared(beg, len - beg).dup(), StringSupport.CR_UNKNOWN, null));
}
}

@@ -519,7 +521,7 @@ public EscapeNode(RubyContext context, SourceSection sourceSection) {
@TruffleBoundary
@Specialization(guards = "isRubyString(pattern)")
public DynamicObject escape(DynamicObject pattern) {
return createString(org.jruby.RubyRegexp.quote19(new ByteList(Layouts.STRING.getByteList(pattern)), true).toString());
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(org.jruby.RubyRegexp.quote19(new ByteList(Layouts.STRING.getByteList(pattern)), true).toString(), UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
}

}
@@ -569,12 +571,12 @@ public QuoteNode(RubyContext context, SourceSection sourceSection) {
@Specialization(guards = "isRubyString(raw)")
public DynamicObject quoteString(DynamicObject raw) {
boolean isAsciiOnly = Layouts.STRING.getByteList(raw).getEncoding().isAsciiCompatible() && StringNodes.scanForCodeRange(raw) == CR_7BIT;
return createString(org.jruby.RubyRegexp.quote19(Layouts.STRING.getByteList(raw), isAsciiOnly));
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), org.jruby.RubyRegexp.quote19(Layouts.STRING.getByteList(raw), isAsciiOnly), StringSupport.CR_UNKNOWN, null);
}

@Specialization(guards = "isRubySymbol(raw)")
public DynamicObject quoteSymbol(DynamicObject raw) {
return quoteString(StringNodes.createString(Layouts.MODULE.getFields(Layouts.BASIC_OBJECT.getLogicalClass(raw)).getContext().getCoreLibrary().getStringClass(), Layouts.SYMBOL.getString(raw)));
return quoteString(Layouts.STRING.createString(Layouts.CLASS.getInstanceFactory(Layouts.MODULE.getFields(Layouts.BASIC_OBJECT.getLogicalClass(raw)).getContext().getCoreLibrary().getStringClass()), RubyString.encodeBytelist(Layouts.SYMBOL.getString(raw), UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null));
}

}
@@ -602,7 +604,7 @@ public SourceNode(RubyContext context, SourceSection sourceSection) {

@Specialization
public DynamicObject source(DynamicObject regexp) {
return createString(Layouts.REGEXP.getSource(regexp).dup());
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), Layouts.REGEXP.getSource(regexp).dup(), StringSupport.CR_UNKNOWN, null);
}

}
@@ -617,7 +619,7 @@ public ToSNode(RubyContext context, SourceSection sourceSection) {
@TruffleBoundary
@Specialization
public DynamicObject toS(DynamicObject regexp) {
return createString(((org.jruby.RubyString) org.jruby.RubyRegexp.newRegexp(getContext().getRuntime(), Layouts.REGEXP.getSource(regexp), Layouts.REGEXP.getRegex(regexp).getOptions()).to_s()).getByteList());
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), ((org.jruby.RubyString) org.jruby.RubyRegexp.newRegexp(getContext().getRuntime(), Layouts.REGEXP.getSource(regexp), Layouts.REGEXP.getRegex(regexp).getOptions()).to_s()).getByteList(), StringSupport.CR_UNKNOWN, null);
}

}
@@ -661,7 +663,7 @@ public Object rubiniusNames(VirtualFrame frame, DynamicObject regexp) {
final DynamicObject name = getSymbol(new ByteList(e.name, e.nameP, e.nameEnd - e.nameP, false));

final int[] backrefs = e.getBackRefs();
final DynamicObject backrefsRubyArray = ArrayNodes.createGeneralArray(getContext().getCoreLibrary().getArrayClass(), backrefs, backrefs.length);
final DynamicObject backrefsRubyArray = Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), backrefs, backrefs.length);

lookupTableWriteNode.call(frame, namesLookupTable, "[]=", null, name, backrefsRubyArray);
}
75 changes: 26 additions & 49 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/StringNodes.java
Original file line number Diff line number Diff line change
@@ -41,6 +41,7 @@
import org.jcodings.specific.USASCIIEncoding;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.Ruby;
import org.jruby.RubyString;
import org.jruby.runtime.Helpers;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
@@ -55,6 +56,8 @@
import org.jruby.truffle.nodes.core.fixnum.FixnumLowerNodeGen;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.nodes.objects.AllocateObjectNode;
import org.jruby.truffle.nodes.objects.AllocateObjectNodeGen;
import org.jruby.truffle.nodes.objects.IsFrozenNode;
import org.jruby.truffle.nodes.objects.IsFrozenNodeGen;
import org.jruby.truffle.nodes.rubinius.ByteArrayNodes;
@@ -70,7 +73,6 @@
import org.jruby.util.io.EncodingUtils;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.Arrays;

@CoreClass(name = "String")
@@ -208,36 +210,6 @@ public static boolean singleByteOptimizable(DynamicObject string) {
return StringSupport.isSingleByteOptimizable(getCodeRangeable(string), EncodingUtils.STR_ENC_GET(getCodeRangeable(string)));
}

public static DynamicObject createEmptyString(DynamicObject stringClass) {
return createString(stringClass, new ByteList());
}

public static DynamicObject createString(DynamicObject stringClass, String string) {
return createString(stringClass, string, UTF8Encoding.INSTANCE);
}

@TruffleBoundary
public static DynamicObject createString(DynamicObject stringClass, String string, Encoding encoding) {
return createString(stringClass, org.jruby.RubyString.encodeBytelist(string, encoding));
}

public static DynamicObject createString(DynamicObject stringClass, byte[] bytes) {
return createString(stringClass, new ByteList(bytes));
}

public static DynamicObject createString(DynamicObject stringClass, ByteBuffer bytes) {
return createString(stringClass, new ByteList(bytes.array()));
}

public static DynamicObject createString(DynamicObject stringClass, ByteList bytes) {
assert RubyGuards.isRubyClass(stringClass);
return Layouts.STRING.createString(Layouts.CLASS.getInstanceFactory(stringClass), bytes, StringSupport.CR_UNKNOWN, null);
}

public static DynamicObject createString(DynamicObjectFactory stringFactory, ByteList bytes) {
return Layouts.STRING.createString(stringFactory, bytes, StringSupport.CR_UNKNOWN, null);
}

@CoreMethod(names = "allocate", constructor = true)
public abstract static class AllocateNode extends CoreMethodArrayArgumentsNode {

@@ -272,7 +244,7 @@ public AddNode(RubyContext context, SourceSection sourceSection) {
@Specialization(guards = "isRubyString(other)")
public DynamicObject add(DynamicObject string, DynamicObject other) {
final Encoding enc = checkEncoding(string, getCodeRangeable(other), this);
final DynamicObject ret = createString(StringSupport.addByteLists(Layouts.STRING.getByteList(string), Layouts.STRING.getByteList(other)));
final DynamicObject ret = Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), StringSupport.addByteLists(Layouts.STRING.getByteList(string), Layouts.STRING.getByteList(other)), StringSupport.CR_UNKNOWN, null);

if (taintResultNode == null) {
CompilerDirectives.transferToInterpreter();
@@ -293,9 +265,11 @@ public abstract static class MulNode extends CoreMethodArrayArgumentsNode {
private final ConditionProfile negativeTimesProfile = ConditionProfile.createBinaryProfile();

@Child private ToIntNode toIntNode;
@Child private AllocateObjectNode allocateObjectNode;

public MulNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
allocateObjectNode = AllocateObjectNodeGen.create(context, sourceSection, null, null);
}

@Specialization
@@ -313,7 +287,7 @@ public DynamicObject multiply(DynamicObject string, int times) {
}

outputBytes.setEncoding(inputBytes.getEncoding());
final DynamicObject ret = StringNodes.createString(Layouts.BASIC_OBJECT.getLogicalClass(string), outputBytes);
final DynamicObject ret = allocateObjectNode.allocate(Layouts.BASIC_OBJECT.getLogicalClass(string), outputBytes, StringSupport.CR_UNKNOWN, null);
Layouts.STRING.setCodeRange(ret, Layouts.STRING.getCodeRange(string));

return ret;
@@ -362,7 +336,7 @@ public boolean equal(VirtualFrame frame, DynamicObject a, Object b) {
respondToNode = insert(KernelNodesFactory.RespondToNodeFactory.create(getContext(), getSourceSection(), null, null, null));
}

if (respondToNode.doesRespondToString(frame, b, StringNodes.createString(getContext().getCoreLibrary().getStringClass(), "to_str"), false)) {
if (respondToNode.doesRespondToString(frame, b, Layouts.STRING.createString(Layouts.CLASS.getInstanceFactory(getContext().getCoreLibrary().getStringClass()), RubyString.encodeBytelist("to_str", UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null), false)) {
if (objectEqualNode == null) {
CompilerDirectives.transferToInterpreter();
objectEqualNode = insert(DispatchHeadNodeFactory.createMethodCall(getContext()));
@@ -410,7 +384,7 @@ public Object compare(VirtualFrame frame, DynamicObject a, Object b) {
respondToToStrNode = insert(KernelNodesFactory.RespondToNodeFactory.create(getContext(), getSourceSection(), null, null, null));
}

if (respondToToStrNode.doesRespondToString(frame, b, StringNodes.createString(getContext().getCoreLibrary().getStringClass(), "to_str"), false)) {
if (respondToToStrNode.doesRespondToString(frame, b, Layouts.STRING.createString(Layouts.CLASS.getInstanceFactory(getContext().getCoreLibrary().getStringClass()), RubyString.encodeBytelist("to_str", UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null), false)) {
if (toStrNode == null) {
CompilerDirectives.transferToInterpreter();
toStrNode = insert(ToStrNodeGen.create(getContext(), getSourceSection(), null));
@@ -434,7 +408,7 @@ public Object compare(VirtualFrame frame, DynamicObject a, Object b) {
respondToCmpNode = insert(KernelNodesFactory.RespondToNodeFactory.create(getContext(), getSourceSection(), null, null, null));
}

if (respondToCmpNode.doesRespondToString(frame, b, StringNodes.createString(getContext().getCoreLibrary().getStringClass(), "<=>"), false)) {
if (respondToCmpNode.doesRespondToString(frame, b, Layouts.STRING.createString(Layouts.CLASS.getInstanceFactory(getContext().getCoreLibrary().getStringClass()), RubyString.encodeBytelist("<=>", UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null), false)) {
if (cmpNode == null) {
CompilerDirectives.transferToInterpreter();
cmpNode = insert(DispatchHeadNodeFactory.createMethodCall(getContext()));
@@ -642,7 +616,7 @@ private Object sliceRange(VirtualFrame frame, DynamicObject string, int begin, i
if (begin == stringLength) {
final ByteList byteList = new ByteList();
byteList.setEncoding(Layouts.STRING.getByteList(string).getEncoding());
return StringNodes.createString(Layouts.BASIC_OBJECT.getLogicalClass(string), byteList);
return Layouts.STRING.createString(Layouts.CLASS.getInstanceFactory(Layouts.BASIC_OBJECT.getLogicalClass(string)), byteList, StringSupport.CR_UNKNOWN, null);
}

end = normalizeIndex(stringLength, end);
@@ -772,7 +746,7 @@ public BNode(RubyContext context, SourceSection sourceSection) {
public DynamicObject b(DynamicObject string) {
final ByteList bytes = Layouts.STRING.getByteList(string).dup();
bytes.setEncoding(ASCIIEncoding.INSTANCE);
return StringNodes.createString(getContext().getCoreLibrary().getStringClass(), bytes);
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), bytes, StringSupport.CR_UNKNOWN, null);
}

}
@@ -794,7 +768,7 @@ public DynamicObject bytes(DynamicObject string) {
store[n] = ((int) bytes[n]) & 0xFF;
}

return createArray(store, bytes.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), store, bytes.length);
}

}
@@ -977,7 +951,7 @@ public Object crypt(DynamicObject string, DynamicObject salt) {

final Encoding ascii8bit = getContext().getRuntime().getEncodingService().getAscii8bitEncoding();
ByteList otherBL = Layouts.STRING.getByteList(salt).dup();
final DynamicObject otherStr = StringNodes.createString(getContext().getCoreLibrary().getStringClass(), otherBL);
final DynamicObject otherStr = Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), otherBL, StringSupport.CR_UNKNOWN, null);

modify(otherStr);
StringSupport.associateEncoding(getCodeRangeable(otherStr), ascii8bit);
@@ -1005,7 +979,7 @@ public Object crypt(DynamicObject string, DynamicObject salt) {
throw new RaiseException(getContext().getCoreLibrary().errnoError(posix.errno(), this));
}

final DynamicObject result = StringNodes.createString(getContext().getCoreLibrary().getStringClass(), new ByteList(cryptedString, 0, cryptedString.length - 1));
final DynamicObject result = Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), new ByteList(cryptedString, 0, cryptedString.length - 1), StringSupport.CR_UNKNOWN, null);
StringSupport.associateEncoding(getCodeRangeable(result), ascii8bit);

return result;
@@ -1095,7 +1069,7 @@ public DowncaseNode(RubyContext context, SourceSection sourceSection) {
@Specialization
public DynamicObject downcase(DynamicObject string) {
final ByteList newByteList = StringNodesHelper.downcase(getContext().getRuntime(), Layouts.STRING.getByteList(string));
return StringNodes.createString(Layouts.BASIC_OBJECT.getLogicalClass(string), newByteList);
return Layouts.STRING.createString(Layouts.CLASS.getInstanceFactory(Layouts.BASIC_OBJECT.getLogicalClass(string)), newByteList, StringSupport.CR_UNKNOWN, null);
}
}

@@ -1215,7 +1189,7 @@ private Object substr(DynamicObject string, int beg, int len) {
taintResultNode = insert(new TaintResultNode(getContext(), getSourceSection()));
}

final DynamicObject ret = StringNodes.createString(Layouts.BASIC_OBJECT.getLogicalClass(string), substringBytes);
final DynamicObject ret = Layouts.STRING.createString(Layouts.CLASS.getInstanceFactory(Layouts.BASIC_OBJECT.getLogicalClass(string)), substringBytes, StringSupport.CR_UNKNOWN, null);

return taintResultNode.maybeTaint(string, ret);
}
@@ -1333,7 +1307,7 @@ public InspectNode(RubyContext context, SourceSection sourceSection) {
@Specialization
public DynamicObject inspect(DynamicObject string) {
final org.jruby.RubyString inspected = (org.jruby.RubyString) org.jruby.RubyString.inspect19(getContext().getRuntime(), Layouts.STRING.getByteList(string));
return StringNodes.createString(getContext().getCoreLibrary().getStringClass(), inspected.getByteList());
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), inspected.getByteList(), StringSupport.CR_UNKNOWN, null);
}
}

@@ -1713,8 +1687,11 @@ public DynamicObject swapcaseSingleByte(DynamicObject string) {
@ImportStatic(StringGuards.class)
public abstract static class DumpNode extends CoreMethodArrayArgumentsNode {

@Child private AllocateObjectNode allocateObjectNode;

public DumpNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
allocateObjectNode = AllocateObjectNodeGen.create(context, sourceSection, null, null);
}

@Specialization(guards = "isAsciiCompatible(string)")
@@ -1723,7 +1700,7 @@ public DynamicObject dumpAsciiCompatible(DynamicObject string) {

ByteList outputBytes = dumpCommon(string);

final DynamicObject result = StringNodes.createString(Layouts.BASIC_OBJECT.getLogicalClass(string), outputBytes);
final DynamicObject result = allocateObjectNode.allocate(Layouts.BASIC_OBJECT.getLogicalClass(string), outputBytes, StringSupport.CR_UNKNOWN, null);
Layouts.STRING.getByteList(result).setEncoding(Layouts.STRING.getByteList(string).getEncoding());
Layouts.STRING.setCodeRange(result, StringSupport.CR_7BIT);

@@ -1747,7 +1724,7 @@ public DynamicObject dump(DynamicObject string) {
outputBytes.append((byte) '"');
outputBytes.append((byte) ')');

final DynamicObject result = StringNodes.createString(Layouts.BASIC_OBJECT.getLogicalClass(string), outputBytes);
final DynamicObject result = Layouts.STRING.createString(Layouts.CLASS.getInstanceFactory(Layouts.BASIC_OBJECT.getLogicalClass(string)), outputBytes, StringSupport.CR_UNKNOWN, null);
Layouts.STRING.getByteList(result).setEncoding(ASCIIEncoding.INSTANCE);
Layouts.STRING.setCodeRange(result, StringSupport.CR_7BIT);

@@ -1927,9 +1904,9 @@ public SuccNode(RubyContext context, SourceSection sourceSection) {
@Specialization
public DynamicObject succ(DynamicObject string) {
if (length(string) > 0) {
return StringNodes.createString(Layouts.BASIC_OBJECT.getLogicalClass(string), StringSupport.succCommon(getContext().getRuntime(), Layouts.STRING.getByteList(string)));
return Layouts.STRING.createString(Layouts.CLASS.getInstanceFactory(Layouts.BASIC_OBJECT.getLogicalClass(string)), StringSupport.succCommon(getContext().getRuntime(), Layouts.STRING.getByteList(string)), StringSupport.CR_UNKNOWN, null);
} else {
return StringNodes.createEmptyString(Layouts.BASIC_OBJECT.getLogicalClass(string));
return Layouts.STRING.createString(Layouts.CLASS.getInstanceFactory(Layouts.BASIC_OBJECT.getLogicalClass(string)), new ByteList(), StringSupport.CR_UNKNOWN, null);
}
}
}
@@ -2260,7 +2237,7 @@ public UpcaseNode(RubyContext context, SourceSection sourceSection) {
@Specialization
public DynamicObject upcase(DynamicObject string) {
final ByteList byteListString = StringNodesHelper.upcase(getContext().getRuntime(), Layouts.STRING.getByteList(string));
return StringNodes.createString(Layouts.BASIC_OBJECT.getLogicalClass(string), byteListString);
return Layouts.STRING.createString(Layouts.CLASS.getInstanceFactory(Layouts.BASIC_OBJECT.getLogicalClass(string)), byteListString, StringSupport.CR_UNKNOWN, null);
}

}
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.truffle.runtime.methods.Arity;
import org.jruby.truffle.runtime.methods.SharedMethodInfo;
import org.jruby.util.StringSupport;

@CoreClass(name = "Symbol")
public abstract class SymbolNodes {
@@ -56,7 +57,8 @@ public AllSymbolsNode(RubyContext context, SourceSection sourceSection) {
@TruffleBoundary
@Specialization
public DynamicObject allSymbols() {
return createArrayWith(getContext().getSymbolTable().allSymbols().toArray());
Object[] store = getContext().getSymbolTable().allSymbols().toArray();
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), store, store.length);
}

}
@@ -166,7 +168,7 @@ public ToSNode(RubyContext context, SourceSection sourceSection) {

@Specialization
public DynamicObject toS(DynamicObject symbol) {
return createString(Layouts.SYMBOL.getByteList(symbol).dup());
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), Layouts.SYMBOL.getByteList(symbol).dup(), StringSupport.CR_UNKNOWN, null);
}

}
Original file line number Diff line number Diff line change
@@ -13,10 +13,13 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.RubyString;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.backtrace.Activation;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.truffle.runtime.layouts.ThreadBacktraceLocationLayoutImpl;
import org.jruby.util.StringSupport;

@CoreClass(name = "Thread::Backtrace::Location")
public class ThreadBacktraceLocationNodes {
@@ -41,12 +44,12 @@ public DynamicObject absolutePath(DynamicObject threadBacktraceLocation) {
final SourceSection sourceSection = activation.getCallNode().getEncapsulatingSourceSection();

if (sourceSection.getSource() == null) {
return createString(sourceSection.getShortDescription());
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(sourceSection.getShortDescription(), UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
}

// TODO CS 30-Apr-15: not absolute - not sure how to solve that

return createString(sourceSection.getSource().getPath());
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(sourceSection.getSource().getPath(), UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
}

}
@@ -85,13 +88,13 @@ public DynamicObject toS(DynamicObject threadBacktraceLocation) {
final SourceSection sourceSection = activation.getCallNode().getEncapsulatingSourceSection();

if (sourceSection.getSource() == null) {
return createString(sourceSection.getShortDescription());
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(sourceSection.getShortDescription(), UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
}

return createString(String.format("%s:%d:in `%s'",
sourceSection.getSource().getShortName(),
sourceSection.getStartLine(),
sourceSection.getIdentifier()));
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(String.format("%s:%d:in `%s'",
sourceSection.getSource().getShortName(),
sourceSection.getStartLine(),
sourceSection.getIdentifier()), UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
}

}
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@
import org.jruby.truffle.runtime.subsystems.FiberManager;
import org.jruby.truffle.runtime.subsystems.SafepointAction;
import org.jruby.truffle.runtime.subsystems.ThreadManager;
import org.jruby.util.StringSupport;

import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
@@ -352,7 +353,7 @@ public Object status(DynamicObject self) {
}
}

return createString(Layouts.THREAD.getStatus(self).bytes);
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), Layouts.THREAD.getStatus(self).bytes, StringSupport.CR_UNKNOWN, null);
}

}
@@ -466,7 +467,7 @@ public ListNode(RubyContext context, SourceSection sourceSection) {
@Specialization
public DynamicObject list() {
final DynamicObject[] threads = getContext().getThreadManager().getThreads();
return createArray(threads, threads.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), threads, threads.length);
}
}

Original file line number Diff line number Diff line change
@@ -19,8 +19,10 @@
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.source.SourceSection;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.Ruby;
import org.jruby.RubyGC;
import org.jruby.RubyString;
import org.jruby.ext.rbconfig.RbConfigLibrary;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.runtime.RubyArguments;
@@ -38,6 +40,7 @@
import org.jruby.truffle.runtime.subsystems.SimpleShell;
import org.jruby.util.ByteList;
import org.jruby.util.Memo;
import org.jruby.util.StringSupport;

import java.util.HashMap;
import java.util.List;
@@ -110,7 +113,7 @@ public String visitFrame(FrameInstance frameInstance) {

});

return createString(source);
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(source, UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
}

}
@@ -182,7 +185,7 @@ public JavaClassOfNode(RubyContext context, SourceSection sourceSection) {

@Specialization
public DynamicObject javaClassOf(Object value) {
return createString(value.getClass().getSimpleName());
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(value.getClass().getSimpleName(), UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
}

}
@@ -205,7 +208,7 @@ public DynamicObject dumpString(DynamicObject string) {
builder.append(String.format("\\x%02x", byteList.get(i)));
}

return createString(builder.toString());
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(builder.toString(), UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
}

}
@@ -249,7 +252,7 @@ public GraalVersionNode(RubyContext context, SourceSection sourceSection) {
@TruffleBoundary
@Specialization
public DynamicObject graalVersion() {
return createString(System.getProperty("graal.version", "unknown"));
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(System.getProperty("graal.version", "unknown"), UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
}

}
@@ -288,11 +291,11 @@ public DynamicObject coverageResult() {

for (Map.Entry<Source, Long[]> source : getContext().getCoverageTracker().getCounts().entrySet()) {
final Object[] store = lineCountsStore(source.getValue());
final DynamicObject array = createArray(store, store.length);
converted.put(createString(source.getKey().getPath()), array);
final DynamicObject array = Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), store, store.length);
converted.put(Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(source.getKey().getPath(), UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null), array);
}

return BucketsStrategy.create(getContext().getCoreLibrary().getHashClass(), converted.entrySet(), false);
return BucketsStrategy.create(getContext(), converted.entrySet(), false);
}

private Object[] lineCountsStore(Long[] array) {
@@ -448,7 +451,7 @@ public JRubyHomeDirectoryNode(RubyContext context, SourceSection sourceSection)
@TruffleBoundary
@Specialization
public DynamicObject jrubyHomeDirectory() {
return createString(getContext().getRuntime().getJRubyHome());
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(getContext().getRuntime().getJRubyHome(), UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
}

}
@@ -462,7 +465,7 @@ public HostOSNode(RubyContext context, SourceSection sourceSection) {

@Specialization
public DynamicObject hostOS() {
return createString(RbConfigLibrary.getOSName());
return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(RbConfigLibrary.getOSName(), UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
}

}
Original file line number Diff line number Diff line change
@@ -15,12 +15,13 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.RubyString;
import org.jruby.ast.ArgsNode;
import org.jruby.runtime.ArgumentDescriptor;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.Visibility;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.core.array.ArrayNodes;
import org.jruby.truffle.nodes.methods.CanBindMethodToModuleNode;
import org.jruby.truffle.nodes.methods.CanBindMethodToModuleNodeGen;
import org.jruby.truffle.nodes.objects.MetaClassNode;
@@ -29,6 +30,7 @@
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.truffle.runtime.methods.InternalMethod;
import org.jruby.util.StringSupport;

@CoreClass(name = "UnboundMethod")
public abstract class UnboundMethodNodes {
@@ -185,10 +187,9 @@ public Object sourceLocation(DynamicObject unboundMethod) {
if (sourceSection.getSource() == null) {
return nil();
} else {
DynamicObject file = createString(sourceSection.getSource().getName());
DynamicObject arrayClass = getContext().getCoreLibrary().getArrayClass();
DynamicObject file = Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist(sourceSection.getSource().getName(), UTF8Encoding.INSTANCE), StringSupport.CR_UNKNOWN, null);
Object[] objects = new Object[]{file, sourceSection.getStartLine()};
return ArrayNodes.createGeneralArray(arrayClass, objects, objects.length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), objects, objects.length);
}
}

Original file line number Diff line number Diff line change
@@ -44,10 +44,6 @@ public ArrayBuilderNode(RubyContext context) {
public abstract Object appendValue(Object store, int index, Object value);
public abstract Object finish(Object store, int length);

public DynamicObject finishAndCreate(DynamicObject arrayClass, Object store, int length) {
return ArrayNodes.createGeneralArray(arrayClass, finish(store, length), length);
}

protected RubyContext getContext() {
return context;
}
Original file line number Diff line number Diff line change
@@ -63,7 +63,7 @@ private DynamicObject executeSingle(VirtualFrame frame, Object store, int length
store = arrayBuilderNode.appendValue(store, length, childObject);
length++;
}
return ArrayNodes.createGeneralArray(getContext().getCoreLibrary().getArrayClass(), arrayBuilderNode.finish(store, length), length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), arrayBuilderNode.finish(store, length), length);
}

@ExplodeLoop
@@ -85,7 +85,7 @@ private DynamicObject executeRubyArray(VirtualFrame frame, Object store, int len
}
}

return ArrayNodes.createGeneralArray(getContext().getCoreLibrary().getArrayClass(), arrayBuilderNode.finish(store, length), length);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), arrayBuilderNode.finish(store, length), length);
}

@ExplodeLoop
Original file line number Diff line number Diff line change
@@ -36,17 +36,17 @@ public ArrayDropTailNode(RubyContext context, SourceSection sourceSection, int i
public DynamicObject getHeadNull(DynamicObject array) {
CompilerDirectives.transferToInterpreter();

return createEmptyArray();
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0);
}

@Specialization(guards = {"isRubyArray(array)", "isIntArray(array)"})
public DynamicObject getHeadIntegerFixnum(DynamicObject array) {
CompilerDirectives.transferToInterpreter();

if (index >= Layouts.ARRAY.getSize(array)) {
return createEmptyArray();
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0);
} else {
return createArray(ArrayUtils.extractRange((int[]) Layouts.ARRAY.getStore(array), 0, Layouts.ARRAY.getSize(array) - index), Layouts.ARRAY.getSize(array) - index);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), ArrayUtils.extractRange((int[]) Layouts.ARRAY.getStore(array), 0, Layouts.ARRAY.getSize(array) - index), Layouts.ARRAY.getSize(array) - index);
}
}

@@ -55,10 +55,10 @@ public DynamicObject geHeadLongFixnum(DynamicObject array) {
CompilerDirectives.transferToInterpreter();

if (index >= Layouts.ARRAY.getSize(array)) {
return createEmptyArray();
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0);
} else {
final int size = Layouts.ARRAY.getSize(array) - index;
return createArray(ArrayUtils.extractRange((long[]) Layouts.ARRAY.getStore(array), 0, size), size);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), ArrayUtils.extractRange((long[]) Layouts.ARRAY.getStore(array), 0, size), size);
}
}

@@ -67,10 +67,10 @@ public DynamicObject getHeadFloat(DynamicObject array) {
CompilerDirectives.transferToInterpreter();

if (index >= Layouts.ARRAY.getSize(array)) {
return createEmptyArray();
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0);
} else {
final int size = Layouts.ARRAY.getSize(array) - index;
return createArray(ArrayUtils.extractRange((double[]) Layouts.ARRAY.getStore(array), 0, size), size);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), ArrayUtils.extractRange((double[]) Layouts.ARRAY.getStore(array), 0, size), size);
}
}

@@ -79,10 +79,10 @@ public DynamicObject getHeadObject(DynamicObject array) {
CompilerDirectives.transferToInterpreter();

if (index >= Layouts.ARRAY.getSize(array)) {
return createEmptyArray();
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0);
} else {
final int size = Layouts.ARRAY.getSize(array) - index;
return createArray(ArrayUtils.extractRange((Object[]) Layouts.ARRAY.getStore(array), 0, size), size);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), ArrayUtils.extractRange((Object[]) Layouts.ARRAY.getStore(array), 0, size), size);
}
}

Original file line number Diff line number Diff line change
@@ -36,17 +36,17 @@ public ArrayGetTailNode(RubyContext context, SourceSection sourceSection, int in
public DynamicObject getTailNull(DynamicObject array) {
CompilerDirectives.transferToInterpreter();

return createEmptyArray();
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0);
}

@Specialization(guards = {"isRubyArray(array)", "isIntArray(array)"})
public DynamicObject getTailIntegerFixnum(DynamicObject array) {
CompilerDirectives.transferToInterpreter();

if (index >= Layouts.ARRAY.getSize(array)) {
return createEmptyArray();
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0);
} else {
return createArray(ArrayUtils.extractRange((int[]) Layouts.ARRAY.getStore(array), index, Layouts.ARRAY.getSize(array)), Layouts.ARRAY.getSize(array) - index);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), ArrayUtils.extractRange((int[]) Layouts.ARRAY.getStore(array), index, Layouts.ARRAY.getSize(array)), Layouts.ARRAY.getSize(array) - index);
}
}

@@ -55,9 +55,9 @@ public DynamicObject getTailLongFixnum(DynamicObject array) {
CompilerDirectives.transferToInterpreter();

if (index >= Layouts.ARRAY.getSize(array)) {
return createEmptyArray();
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0);
} else {
return createArray(ArrayUtils.extractRange((long[]) Layouts.ARRAY.getStore(array), index, Layouts.ARRAY.getSize(array)), Layouts.ARRAY.getSize(array) - index);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), ArrayUtils.extractRange((long[]) Layouts.ARRAY.getStore(array), index, Layouts.ARRAY.getSize(array)), Layouts.ARRAY.getSize(array) - index);
}
}

@@ -66,9 +66,9 @@ public DynamicObject getTailFloat(DynamicObject array) {
CompilerDirectives.transferToInterpreter();

if (index >= Layouts.ARRAY.getSize(array)) {
return createEmptyArray();
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0);
} else {
return createArray(ArrayUtils.extractRange((double[]) Layouts.ARRAY.getStore(array), index, Layouts.ARRAY.getSize(array)), Layouts.ARRAY.getSize(array) - index);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), ArrayUtils.extractRange((double[]) Layouts.ARRAY.getStore(array), index, Layouts.ARRAY.getSize(array)), Layouts.ARRAY.getSize(array) - index);
}
}

@@ -77,9 +77,9 @@ public DynamicObject getTailObject(DynamicObject array) {
CompilerDirectives.transferToInterpreter();

if (index >= Layouts.ARRAY.getSize(array)) {
return createEmptyArray();
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0);
} else {
return createArray(ArrayUtils.extractRange((Object[]) Layouts.ARRAY.getStore(array), index, Layouts.ARRAY.getSize(array)), Layouts.ARRAY.getSize(array) - index);
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), ArrayUtils.extractRange((Object[]) Layouts.ARRAY.getStore(array), index, Layouts.ARRAY.getSize(array)), Layouts.ARRAY.getSize(array) - index);
}
}

Loading

0 comments on commit 08f77c6

Please sign in to comment.