Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 617be2d793c2
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: b96bdcf9e099
Choose a head ref
  • 4 commits
  • 23 files changed
  • 1 contributor

Commits on Apr 28, 2016

  1. Copy the full SHA
    e643147 View commit details
  2. Copy the full SHA
    68e9995 View commit details
  3. [Truffle] Truffle::Fixnum.lower

    Might start in general putting Ruby core methods into X, and supporting methods into Truffle::X
    chrisseaton committed Apr 28, 2016
    Copy the full SHA
    2193aa5 View commit details
  4. [Truffle] Truffle::Safe

    chrisseaton committed Apr 28, 2016
    Copy the full SHA
    b96bdcf View commit details
16 changes: 8 additions & 8 deletions spec/truffle/specs/truffle/fixnum/and_spec.rb
Original file line number Diff line number Diff line change
@@ -11,30 +11,30 @@
describe "Fixnum#&" do
before :each do
@long = (1 << 48) + 1
@mask = Truffle.fixnum_lower((1 << 30) - 1)
@mask = Truffle::Fixnum.lower((1 << 30) - 1)
end

it "returns an int for (int, int)" do
result = (1 & 3)
result.should == 1
Truffle::Runtime.java_class_of(result).should == 'Integer'
Truffle.java_class_of(result).should == 'Integer'
end

it "returns an int for (long, int)" do
Truffle::Runtime.java_class_of(@long).should == 'Long'
Truffle::Runtime.java_class_of(@mask).should == 'Integer'
Truffle.java_class_of(@long).should == 'Long'
Truffle.java_class_of(@mask).should == 'Integer'

result = (@long & @mask)
result.should == 1
Truffle::Runtime.java_class_of(result).should == 'Integer'
Truffle.java_class_of(result).should == 'Integer'
end

it "returns an int for (int, long)" do
Truffle::Runtime.java_class_of(@long).should == 'Long'
Truffle::Runtime.java_class_of(@mask).should == 'Integer'
Truffle.java_class_of(@long).should == 'Long'
Truffle.java_class_of(@mask).should == 'Integer'

result = (@mask & @long)
result.should == 1
Truffle::Runtime.java_class_of(result).should == 'Integer'
Truffle.java_class_of(result).should == 'Integer'
end
end
Original file line number Diff line number Diff line change
@@ -6,36 +6,36 @@
# GNU General Public License version 2
# GNU Lesser General Public License version 2.1

require_relative '../../../../ruby/spec_helper'
require_relative '../../../ruby/spec_helper'

describe "Truffle::Runtime.java_class_of" do
describe "Truffle.java_class_of" do

it "returns a String" do
Truffle::Runtime.java_class_of(14).should be_kind_of(String)
Truffle.java_class_of(14).should be_kind_of(String)
end

it "returns 'Boolean' for true" do
Truffle::Runtime.java_class_of(true).should == 'Boolean'
Truffle.java_class_of(true).should == 'Boolean'
end

it "returns 'Boolean' for false" do
Truffle::Runtime.java_class_of(false).should == 'Boolean'
Truffle.java_class_of(false).should == 'Boolean'
end

it "returns 'Integer' for a small Fixnum" do
Truffle::Runtime.java_class_of(14).should == 'Integer'
Truffle.java_class_of(14).should == 'Integer'
end

it "returns 'Long' for a large Fixnum" do
Truffle::Runtime.java_class_of(0xffffffffffff).should == 'Long'
Truffle.java_class_of(0xffffffffffff).should == 'Long'
end

it "returns 'Double' for a Float" do
Truffle::Runtime.java_class_of(3.14).should == 'Double'
Truffle.java_class_of(3.14).should == 'Double'
end

it "returns 'DynamicObject*' for a String" do
Truffle::Runtime.java_class_of('test').start_with?('DynamicObject').should be_true
Truffle.java_class_of('test').start_with?('DynamicObject').should be_true
end

end
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@

require_relative '../../../../ruby/spec_helper'

describe "Truffle::Runtime.debug_print" do
describe "Truffle::Ropes.debug_print" do

it "needs to be reviewed for spec completeness"

Original file line number Diff line number Diff line change
@@ -8,18 +8,18 @@

require_relative '../../../../ruby/spec_helper'

describe "Truffle::Runtime.dump_string" do
describe "Truffle::Ropes.dump_string" do

it "returns a String" do
Truffle::Runtime.dump_string('foo').should be_kind_of(String)
Truffle::Ropes.dump_string('foo').should be_kind_of(String)
end

it "returns a sequence of escaped bytes in lower case" do
Truffle::Runtime.dump_string('foo').should =~ /(\\x[0-9a-f][0-9a-f])+/
Truffle::Ropes.dump_string('foo').should =~ /(\\x[0-9a-f][0-9a-f])+/
end

it "returns correct bytes for the given string" do
Truffle::Runtime.dump_string('foo').should == "\\x66\\x6f\\x6f"
Truffle::Ropes.dump_string('foo').should == "\\x66\\x6f\\x6f"
end

end
2 changes: 1 addition & 1 deletion spec/truffle/tags/truffle/runtime/java_class_of_tags.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
graalvm:Truffle::Runtime.java_class_of returns 'DynamicObject*' for a String
graalvm:Truffle.java_class_of returns 'DynamicObject*' for a String
6 changes: 3 additions & 3 deletions test/truffle/integration/safe.sh
Original file line number Diff line number Diff line change
@@ -18,11 +18,11 @@ safe -e 14

# Check our safe_puts is safe

safe -e "Truffle.safe_puts 'hello, world'"
safe -e "Truffle::Safe.puts 'hello, world'"

# But we can make that unsafe as well if really don't want any output

unsafe -Xtruffle.platform.safe_puts=false -e "Truffle.safe_puts 'hello, world'"
unsafe -Xtruffle.platform.safe_puts=false -e "Truffle::Safe.puts 'hello, world'"

# Try some unsafe operations

@@ -38,7 +38,7 @@ safe -Xtruffle.platform.safe.exit=true -e 'exit!'

# Check that safe_puts sanitises correctly

if [[ `run -e "Truffle.safe_puts 'foo © bar'"` != 'foo ? bar' ]]
if [[ `run -e "Truffle::Safe.puts 'foo © bar'"` != 'foo ? bar' ]]
then
echo safe_puts is not sanitising output
exit 1
2 changes: 1 addition & 1 deletion tool/truffle/callgraph2html.rb
Original file line number Diff line number Diff line change
@@ -55,7 +55,7 @@ def core?
end

def hidden?
source.file == 'run_jruby_root' || source.file == 'context' || name == 'Truffle#run_jruby_root' || name == 'Truffle#context'
source.file == 'run_jruby_root' || source.file == 'context' || name == 'Truffle::Boot#run_jruby_root' || name == 'Truffle::Boot#context'
end

def reachable
4 changes: 2 additions & 2 deletions truffle/src/main/java/org/jruby/truffle/JRubyTruffleImpl.java
Original file line number Diff line number Diff line change
@@ -33,7 +33,7 @@ public JRubyTruffleImpl(Ruby runtime) {
.build();

try {
context = (RubyContext) engine.eval(Source.fromText("Truffle.context", "context")
context = (RubyContext) engine.eval(Source.fromText("Truffle::Boot.context", "context")
.withMimeType(RubyLanguage.MIME_TYPE)).get();
} catch (IOException e) {
throw new RuntimeException(e);
@@ -51,7 +51,7 @@ public Object execute(org.jruby.ast.RootNode rootNode) {
context.setInitialJRubyRootNode(rootNode);

try {
return engine.eval(Source.fromText("Truffle.run_jruby_root", "run_jruby_root")
return engine.eval(Source.fromText("Truffle::Boot.run_jruby_root", "run_jruby_root")
.withMimeType(RubyLanguage.MIME_TYPE)).get();
} catch (IOException e) {
if (e.getCause() instanceof ExitException) {
12 changes: 12 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/core/CoreLibrary.java
Original file line number Diff line number Diff line change
@@ -53,13 +53,15 @@
import org.jruby.truffle.core.numeric.FixnumNodesFactory;
import org.jruby.truffle.core.numeric.FloatNodesFactory;
import org.jruby.truffle.core.numeric.IntegerNodesFactory;
import org.jruby.truffle.core.numeric.TruffleFixnumNodesFactory;
import org.jruby.truffle.core.objectspace.ObjectSpaceNodesFactory;
import org.jruby.truffle.core.proc.ProcNodesFactory;
import org.jruby.truffle.core.queue.QueueNodesFactory;
import org.jruby.truffle.core.queue.SizedQueueNodesFactory;
import org.jruby.truffle.core.range.RangeNodesFactory;
import org.jruby.truffle.core.regexp.MatchDataNodesFactory;
import org.jruby.truffle.core.regexp.RegexpNodesFactory;
import org.jruby.truffle.core.rope.TruffleRopesNodesFactory;
import org.jruby.truffle.core.rubinius.AtomicReferenceNodesFactory;
import org.jruby.truffle.core.rubinius.ByteArrayNodesFactory;
import org.jruby.truffle.core.rubinius.PosixNodesFactory;
@@ -80,6 +82,7 @@
import org.jruby.truffle.language.RubyGuards;
import org.jruby.truffle.language.RubyNode;
import org.jruby.truffle.language.RubyRootNode;
import org.jruby.truffle.language.TruffleSafeNodesFactory;
import org.jruby.truffle.language.backtrace.BacktraceFormatter;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.language.control.TruffleFatalException;
@@ -88,6 +91,7 @@
import org.jruby.truffle.language.methods.DeclarationContext;
import org.jruby.truffle.language.methods.InternalMethod;
import org.jruby.truffle.language.objects.FreezeNode;
import org.jruby.truffle.language.BootNodesFactory;
import org.jruby.truffle.language.objects.FreezeNodeGen;
import org.jruby.truffle.language.objects.SingletonClassNode;
import org.jruby.truffle.language.objects.SingletonClassNodeGen;
@@ -569,8 +573,12 @@ public CoreLibrary(RubyContext context) {
defineModule(truffleModule, "Etc");
defineModule(truffleModule, "Coverage");
defineModule(truffleModule, "Graal");
defineModule(truffleModule, "Ropes");
defineModule(truffleModule, "GC");
defineModule(truffleModule, "Attachments");
defineModule(truffleModule, "Boot");
defineModule(truffleModule, "Fixnum");
defineModule(truffleModule, "Safe");
psychModule = defineModule("Psych");
psychParserClass = defineClass(psychModule, objectClass, "Parser");
final DynamicObject psychHandlerClass = defineClass(psychModule, objectClass, "Handler");
@@ -698,6 +706,7 @@ public void addCoreMethods() {
coreMethodNodeManager.addCoreMethodNodes(TrueClassNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(TruffleNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(GCNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(BootNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(AttachmentsNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(GraalNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(EncodingNodesFactory.getFactories());
@@ -720,6 +729,9 @@ public void addCoreMethods() {
coreMethodNodeManager.addCoreMethodNodes(AtomicReferenceNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(TracePointNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(CoverageNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(TruffleRopesNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(TruffleFixnumNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(TruffleSafeNodesFactory.getFactories());

coreMethodNodeManager.allMethodInstalled();

Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.core.numeric;

import com.oracle.truffle.api.dsl.Specialization;
import org.jruby.truffle.core.CoreClass;
import org.jruby.truffle.core.CoreLibrary;
import org.jruby.truffle.core.CoreMethod;
import org.jruby.truffle.core.UnaryCoreMethodNode;

@CoreClass(name = "Truffle::Fixnum")
public abstract class TruffleFixnumNodes {

@CoreMethod(names = "lower", isModuleFunction = true, required = 1)
public abstract static class LowerPrimitiveNode extends UnaryCoreMethodNode {

@Specialization
public int lower(int value) {
return value;
}

@Specialization(guards = "canLower(value)")
public int lower(long value) {
return (int) value;
}

@Specialization(guards = "!canLower(value)")
public long lowerFails(long value) {
return value;
}

protected static boolean canLower(long value) {
return CoreLibrary.fitsIntoInteger(value);
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/*
* Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.core.rope;

import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Cached;
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.truffle.RubyContext;
import org.jruby.truffle.core.CoreClass;
import org.jruby.truffle.core.CoreMethod;
import org.jruby.truffle.core.CoreMethodArrayArgumentsNode;
import org.jruby.truffle.core.string.StringOperations;
import org.jruby.truffle.language.NotProvided;
import org.jruby.truffle.platform.UnsafeGroup;

@CoreClass(name = "Truffle::Ropes")
public abstract class TruffleRopesNodes {

@CoreMethod(names = "debug_print", onSingleton = true, required = 1, unsafe = UnsafeGroup.IO)
public abstract static class DebugPrintNode extends CoreMethodArrayArgumentsNode {

@TruffleBoundary
@Specialization(guards = "isRubyString(string)")
public DynamicObject debugPrint(DynamicObject string) {
System.err.println(string.toString());
return nil();
}

}

@CoreMethod(names = "dump_string", onSingleton = true, required = 1)
public abstract static class DumpStringNode extends CoreMethodArrayArgumentsNode {

@TruffleBoundary
@Specialization(guards = "isRubyString(string)")
public DynamicObject dumpString(DynamicObject string) {
final StringBuilder builder = new StringBuilder();

final Rope rope = StringOperations.rope(string);

for (int i = 0; i < rope.byteLength(); i++) {
builder.append(String.format("\\x%02x", rope.get(i)));
}

return createString(StringOperations.encodeRope(builder.toString(), UTF8Encoding.INSTANCE));
}

}

@CoreMethod(names = "convert_to_mutable_rope", onSingleton = true, required = 1)
public abstract static class ConvertToMutableRope extends CoreMethodArrayArgumentsNode {

@Specialization(guards = "isRubyString(string)")
public DynamicObject convertToMutableRope(DynamicObject string) {
final RopeBuffer ropeBuffer = new RopeBuffer(StringOperations.rope(string));
StringOperations.setRope(string, ropeBuffer);

return string;
}
}

@CoreMethod(names = "debug_print_rope", onSingleton = true, required = 1, optional = 1, unsafe = UnsafeGroup.IO)
public abstract static class DebugPrintRopeNode extends CoreMethodArrayArgumentsNode {

@Child private RopeNodes.DebugPrintRopeNode debugPrintRopeNode;

public DebugPrintRopeNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
debugPrintRopeNode = RopeNodesFactory.DebugPrintRopeNodeGen.create(null, null, null);
}

@TruffleBoundary
@Specialization(guards = "isRubyString(string)")
public DynamicObject debugPrintDefault(DynamicObject string, NotProvided printString) {
return debugPrint(string, true);
}

@TruffleBoundary
@Specialization(guards = "isRubyString(string)")
public DynamicObject debugPrint(DynamicObject string, boolean printString) {
System.err.println("Legend: ");
System.err.println("BN = Bytes Null? (byte[] not yet populated)");
System.err.println("BL = Byte Length");
System.err.println("CL = Character Length");
System.err.println("CR = Code Range");
System.err.println("O = Offset (SubstringRope only)");
System.err.println("T = Times (RepeatingRope only)");
System.err.println("D = Depth");
System.err.println("LD = Left Depth (ConcatRope only)");
System.err.println("RD = Right Depth (ConcatRope only)");

return debugPrintRopeNode.executeDebugPrint(StringOperations.rope(string), 0, printString);
}

}

@CoreMethod(names = "flatten_rope", onSingleton = true, required = 1)
public abstract static class FlattenRopeNode extends CoreMethodArrayArgumentsNode {

@Specialization(guards = "isRubyString(string)")
public DynamicObject flattenRope(DynamicObject string,
@Cached("create()") RopeNodes.FlattenNode flattenNode) {
final Rope flattened = flattenNode.executeFlatten(StringOperations.rope(string));

return createString(flattened);
}

}

/*
* Truffle.create_simple_string creates a string 'test' without any part of the string escaping. Useful
* for testing compilation of String becuase most other ways to construct a string can currently escape.
*/

@CoreMethod(names = "create_simple_string", onSingleton = true)
public abstract static class CreateSimpleStringNode extends CoreMethodArrayArgumentsNode {

@Specialization
public DynamicObject createSimpleString() {
return createString(RopeOperations.create(new byte[]{'t', 'e', 's', 't'}, UTF8Encoding.INSTANCE, CodeRange.CR_7BIT));
}
}

}
356 changes: 0 additions & 356 deletions truffle/src/main/java/org/jruby/truffle/extra/TruffleNodes.java

Large diffs are not rendered by default.

200 changes: 200 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/language/BootNodes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
/*
* Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.language;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.IndirectCallNode;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.Source;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.CoreClass;
import org.jruby.truffle.core.CoreLibrary;
import org.jruby.truffle.core.CoreMethod;
import org.jruby.truffle.core.CoreMethodArrayArgumentsNode;
import org.jruby.truffle.core.CoreMethodNode;
import org.jruby.truffle.core.Layouts;
import org.jruby.truffle.core.string.StringOperations;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.language.loader.CodeLoader;
import org.jruby.truffle.language.loader.SourceLoader;
import org.jruby.truffle.language.methods.DeclarationContext;
import org.jruby.truffle.language.parser.ParserContext;
import org.jruby.truffle.platform.UnsafeGroup;
import org.jruby.util.ByteList;

import java.io.File;
import java.io.IOException;

@CoreClass(name = "Truffle::Boot")
public abstract class BootNodes {

@CoreMethod(names = "jruby_home_directory", onSingleton = true)
public abstract static class JRubyHomeDirectoryNode extends CoreMethodNode {

@TruffleBoundary
@Specialization
public DynamicObject jrubyHomeDirectory() {
return createString(StringOperations.encodeRope(getContext().getJRubyRuntime().getJRubyHome(), UTF8Encoding.INSTANCE));
}

}

@CoreMethod(names = "jruby_home_directory_protocol", onSingleton = true)
public abstract static class JRubyHomeDirectoryProtocolNode extends CoreMethodNode {

@TruffleBoundary
@Specialization
public DynamicObject jrubyHomeDirectoryProtocol() {
String home = getContext().getJRubyRuntime().getJRubyHome();

if (home.startsWith("uri:classloader:")) {
home = home.substring("uri:classloader:".length());

while (home.startsWith("/")) {
home = home.substring(1);
}

home = SourceLoader.JRUBY_SCHEME + "/" + home;
}

return createString(StringOperations.encodeRope(home, UTF8Encoding.INSTANCE));
}

}

@CoreMethod(names = "install_rubinius_primitive", isModuleFunction = true, required = 1)
public abstract static class InstallRubiniusPrimitiveNode extends CoreMethodArrayArgumentsNode {

@Specialization(guards = "isRubyMethod(rubyMethod)")
public Object installRubiniusPrimitive(DynamicObject rubyMethod) {
String name = Layouts.METHOD.getMethod(rubyMethod).getName();
getContext().getRubiniusPrimitiveManager().installPrimitive(name, rubyMethod);
return nil();
}
}

@CoreMethod(names = "context", onSingleton = true)
public abstract static class ContextNode extends CoreMethodArrayArgumentsNode {

@Specialization
public RubyContext context() {
return getContext();
}
}

@CoreMethod(names = "run_jruby_root", onSingleton = true)
public abstract static class RunJRubyRootNode extends CoreMethodArrayArgumentsNode {

@Specialization
public Object runJRubyRootNode(VirtualFrame frame, @Cached("create()")IndirectCallNode callNode) {
coreLibrary().getGlobalVariables().put(
"$0",
StringOperations.createString(getContext(),
ByteList.create(getContext().getJRubyInterop().getArg0())));

String inputFile = getContext().getInitialJRubyRootNode().getPosition().getFile();

final Source source;

try {
if (!inputFile.equals("-e")) {
inputFile = new File(inputFile).getCanonicalPath();
}

source = getContext().getSourceCache().getSource(inputFile);
} catch (IOException e) {
throw new RuntimeException(e);
}

final RubyRootNode rootNode = getContext().getCodeLoader().parse(
source,
UTF8Encoding.INSTANCE,
ParserContext.TOP_LEVEL_FIRST,
null,
true,
null);

final CodeLoader.DeferredCall deferredCall = getContext().getCodeLoader().prepareExecute(
ParserContext.TOP_LEVEL,
DeclarationContext.TOP_LEVEL,
rootNode,
null,
coreLibrary().getMainObject());

return deferredCall.call(frame, callNode);
}
}

@CoreMethod(names = "original_argv", onSingleton = true)
public abstract static class OriginalArgvNode extends CoreMethodNode {

@TruffleBoundary
@Specialization
public DynamicObject originalArgv() {
final String[] argv = getContext().getJRubyInterop().getArgv();
final Object[] array = new Object[argv.length];

for (int n = 0; n < array.length; n++) {
array[n] = StringOperations.createString(getContext(), StringOperations.encodeRope(argv[n], UTF8Encoding.INSTANCE));
}

return Layouts.ARRAY.createArray(coreLibrary().getArrayFactory(), array, array.length);
}

}

@CoreMethod(names = "original_load_path", onSingleton = true)
public abstract static class OriginalLoadPathNode extends CoreMethodNode {

@TruffleBoundary
@Specialization
public DynamicObject originalLoadPath() {
final String[] path = getContext().getJRubyInterop().getOriginalLoadPath();
final Object[] array = new Object[path.length];

for (int n = 0; n < array.length; n++) {
array[n] = StringOperations.createString(getContext(), StringOperations.encodeRope(path[n], UTF8Encoding.INSTANCE));
}

return Layouts.ARRAY.createArray(coreLibrary().getArrayFactory(), array, array.length);
}

}

@CoreMethod(names = "require_core", isModuleFunction = true, required = 1)
public abstract static class RequireCoreNode extends CoreMethodArrayArgumentsNode {

@Specialization(guards = "isRubyString(feature)")
public boolean requireRelative(VirtualFrame frame, DynamicObject feature, @Cached("create()") IndirectCallNode callNode) {
final CoreLibrary coreLibrary = getContext().getCoreLibrary();
if (!(coreLibrary.isLoadingRubyCore() || getContext().getOptions().PLATFORM_SAFE_LOAD)) {
throw new RaiseException(coreExceptions().internalErrorUnsafe(this));
}

final CodeLoader codeLoader = getContext().getCodeLoader();
final String path = coreLibrary.getCoreLoadPath() + "/" + feature.toString() + ".rb";
try {
final RubyRootNode rootNode = codeLoader.parse(getContext().getSourceCache().getSource(path), UTF8Encoding.INSTANCE, ParserContext.TOP_LEVEL, null, true, this);
final CodeLoader.DeferredCall deferredCall = codeLoader.prepareExecute(ParserContext.TOP_LEVEL, DeclarationContext.TOP_LEVEL, rootNode, null, coreLibrary.getMainObject());
deferredCall.callWithoutCallNode();
} catch (IOException e) {
throw new RuntimeException(e);
}

return true;
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.language;

import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.object.DynamicObject;
import org.jruby.truffle.core.CoreClass;
import org.jruby.truffle.core.CoreMethod;
import org.jruby.truffle.core.CoreMethodArrayArgumentsNode;
import org.jruby.truffle.core.CoreMethodNode;
import org.jruby.truffle.platform.UnsafeGroup;

@CoreClass(name = "Truffle::Safe")
public abstract class TruffleSafeNodes {

@CoreMethod(names = "puts", onSingleton = true, required = 1, unsafe = UnsafeGroup.SAFE_PUTS)
public abstract static class PutsNode extends CoreMethodArrayArgumentsNode {

@TruffleBoundary
@Specialization(guards = "isRubyString(string)")
public DynamicObject puts(DynamicObject string) {
for (char c : string.toString().toCharArray()) {
if (isAsciiPrintable(c)) {
System.out.print(c);
} else {
System.out.print('?');
}
}

System.out.println();

return nil();
}

private boolean isAsciiPrintable(char c) {
return c >= 32 && c <= 126 || c == '\n' || c == '\t';
}

}

@CoreMethod(names = "io_safe?", onSingleton = true)
public abstract static class IsIOSafeNode extends CoreMethodNode {

@Specialization
public boolean ioSafe() {
return getContext().getOptions().PLATFORM_SAFE_IO;
}

}

@CoreMethod(names = "memory_safe?", onSingleton = true)
public abstract static class IsMemorySafeNode extends CoreMethodNode {

@Specialization
public boolean memorySafe() {
return getContext().getOptions().PLATFORM_SAFE_MEMORY;
}

}

@CoreMethod(names = "signals_safe?", onSingleton = true)
public abstract static class AreSignalsSafeNode extends CoreMethodNode {

@Specialization
public boolean signalsSafe() {
return getContext().getOptions().PLATFORM_SAFE_SIGNALS;
}

}

}
463 changes: 231 additions & 232 deletions truffle/src/main/ruby/core.rb

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions truffle/src/main/ruby/core/config.rb
Original file line number Diff line number Diff line change
@@ -11,8 +11,8 @@ module RbConfig
'exeext' => '',
'EXEEXT' => '',
'host_os' => Truffle.host_os,
'bindir' => "#{Truffle.jruby_home_directory}/bin",
'libdir' => "#{Truffle.jruby_home_directory}/lib/ruby/truffle",
'bindir' => "#{Truffle::Boot.jruby_home_directory}/bin",
'libdir' => "#{Truffle::Boot.jruby_home_directory}/lib/ruby/truffle",
'ruby_install_name' => 'jruby',
'RUBY_INSTALL_NAME' => 'jruby',
'ruby_version' => '2.2.0',
2 changes: 1 addition & 1 deletion truffle/src/main/ruby/core/main.rb
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@
# GNU General Public License version 2
# GNU Lesser General Public License version 2.1

if Truffle.signals_safe?
if Truffle::Safe.signals_safe?
Signal.trap("INT") do
raise Interrupt
end
6 changes: 3 additions & 3 deletions truffle/src/main/ruby/core/post.rb
Original file line number Diff line number Diff line change
@@ -6,11 +6,11 @@
# GNU General Public License version 2
# GNU Lesser General Public License version 2.1

ARGV.push *Truffle.original_argv
ARGV.push *Truffle::Boot.original_argv

$LOAD_PATH.push *Truffle.original_load_path
$LOAD_PATH.push *Truffle::Boot.original_load_path

home = Truffle.jruby_home_directory_protocol
home = Truffle::Boot.jruby_home_directory_protocol
$LOAD_PATH.push home + '/lib/ruby/truffle/mri'
$LOAD_PATH.push home + '/lib/ruby/truffle/truffle'
$LOAD_PATH.push home + '/lib/ruby/truffle/rubysl/rubysl-strscan/lib'
4 changes: 2 additions & 2 deletions truffle/src/main/ruby/core/rubinius/api/shims/io.rb
Original file line number Diff line number Diff line change
@@ -34,7 +34,7 @@ def initialize

# Truffle: redefine setter to lower
def mode=(value)
@mode = Truffle.fixnum_lower(value)
@mode = Truffle::Fixnum.lower(value)
end

#
@@ -46,7 +46,7 @@ def mode=(value)
# The +sync+ attribute will also be set.
#
def self.setup(io, fd, mode=nil, sync=false)
if Truffle.io_safe?
if Truffle::Safe.io_safe?
cur_mode = FFI::Platform::POSIX.fcntl(fd, F_GETFL, 0)
else
cur_mode = RDONLY if fd == 0
2 changes: 1 addition & 1 deletion truffle/src/main/ruby/core/rubinius/platform/pointer.rb
Original file line number Diff line number Diff line change
@@ -294,7 +294,7 @@ def autorelease?
raise PrimitiveFailure, "FFI::Pointer#pointer_autorelease_p primitive failed"
end

if Truffle.memory_safe?
if Truffle::Safe.memory_safe?
NULL = Pointer.new(0x0)
else
NULL = nil
6 changes: 3 additions & 3 deletions truffle/src/main/ruby/core/rubinius/primitives.rb
Original file line number Diff line number Diff line change
@@ -34,15 +34,15 @@ def self.module_mirror(obj)
end
end

Truffle.install_rubinius_primitive method(:module_mirror)
Truffle::Boot.install_rubinius_primitive method(:module_mirror)

if Truffle::Graal.substrate?

def self.vm_gc_start(force)
Truffle::Interop.execute(Truffle::Interop.read_property(Truffle::Java::System, :gc))
end

Truffle.install_rubinius_primitive method(:vm_gc_start)
Truffle::Boot.install_rubinius_primitive method(:vm_gc_start)

end

@@ -60,6 +60,6 @@ def self.vm_spawn(options, command, arguments)
Truffle.spawn_process command, arguments, env_array
end

Truffle.install_rubinius_primitive method(:vm_spawn)
Truffle::Boot.install_rubinius_primitive method(:vm_spawn)
end
end
4 changes: 2 additions & 2 deletions truffle/src/main/ruby/core/shims.rb
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ def internal_encoding

end

if Truffle.io_safe?
if Truffle::Safe.io_safe?
STDIN = File.new(0)
STDOUT = File.new(1)
STDERR = File.new(2)
@@ -40,7 +40,7 @@ def external_encoding
end
end

if Truffle.io_safe?
if Truffle::Safe.io_safe?
if STDOUT.tty?
STDOUT.sync = true
else
37 changes: 0 additions & 37 deletions truffle/src/main/ruby/core/truffle/runtime.rb

This file was deleted.