Skip to content

Commit

Permalink
Showing 91 changed files with 930 additions and 705 deletions.
8 changes: 4 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -2,9 +2,9 @@ language: java

sudo: false

#cache:
# directories:
# - $HOME/.m2
cache:
directories:
- $HOME/.m2

before_install:
- export MAVEN_SKIP_RC=true
@@ -69,7 +69,7 @@ branches:
- truffle-head
- /^test-.*$/
- /^ha-feature/
- ruby-2.3
- ruby-2.4

script: tool/travis_runner.sh
install: |
1 change: 1 addition & 0 deletions spec/ruby/language/defined_spec.rb
Original file line number Diff line number Diff line change
@@ -764,6 +764,7 @@
end

it "returns nil when a constant is scoped to an undefined constant" do
Object.should_not_receive(:const_missing)
defined?(Undefined::Object).should be_nil
end

1 change: 1 addition & 0 deletions spec/tags/ruby/language/defined_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails(jruby/jruby#3903):The defined? keyword for a scoped constant returns nil when a constant is scoped to an undefined constant
6 changes: 6 additions & 0 deletions test/truffle/integration/js.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env bash

set -e

ruby -X+T test/truffle/integration/js/eval.rb
ruby -X+T test/truffle/integration/js/inline-exported.rb
15 changes: 15 additions & 0 deletions test/truffle/integration/js/eval.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright (c) 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

unless Truffle::Interop.mime_type_supported?('application/javascript')
abort 'JavaScript doesn\'t appear to be available - skipping JavaScript test'
end

if Truffle::Interop.eval('application/javascript', '14 + 2') != 16
abort 'result not as expected'
end
30 changes: 30 additions & 0 deletions test/truffle/integration/js/inline-exported.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright (c) 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

unless Truffle::Interop.mime_type_supported?('application/javascript')
abort 'JavaScript doesn\'t appear to be available - skipping JavaScript test'
end

Truffle::Interop.eval('application/javascript', %{
function clamp(min, max, value) {
if (value < min) {
return min;
} else if (value > max) {
return max;
} else {
return value;
}
}
Interop.export('clamp', clamp.bind(this));
})

Truffle::Interop.import_method(:clamp)

if clamp(10, 90, 46) != 46
abort 'result not as expected'
end
3 changes: 1 addition & 2 deletions test/truffle/integration/r/eval.rb
Original file line number Diff line number Diff line change
@@ -7,8 +7,7 @@
# GNU Lesser General Public License version 2.1

unless Truffle::Interop.mime_type_supported?('application/x-r')
puts "R doesn't appear to be available - skipping R test"
exit
abort 'R doesn\'t appear to be available - skipping R test'
end

if Truffle::Interop.eval('application/x-r', '14 + 2') != 16
5 changes: 5 additions & 0 deletions test/truffle/integration/sl.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash

set -e

ruby -X+T test/truffle/integration/sl/inline-exported.rb
28 changes: 28 additions & 0 deletions test/truffle/integration/sl/inline-exported.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright (c) 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

unless Truffle::Interop.mime_type_supported?('application/x-sl')
abort 'SL doesn\'t appear to be available - skipping SL test'
end

Truffle::Interop.eval('application/x-sl', %{
function clamp(min, max, value) {
if (value < min) {
return min;
}
if (value > max) {
return max;
}
return value;
}})

Truffle::Interop.import_method(:clamp)

if clamp(10, 90, 46) != 46
abort 'result not as expected'
end
22 changes: 20 additions & 2 deletions tool/jt.rb
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ module Utilities

def self.truffle_version
File.foreach("#{JRUBY_DIR}/truffle/pom.rb") do |line|
if /'truffle\.version' => '(\d+\.\d+(?:-SNAPSHOT)?)'/ =~ line
if /'truffle\.version' => '(\d+\.\d+|\h+-SNAPSHOT)'/ =~ line
break $1
end
end
@@ -85,6 +85,12 @@ def self.find_graal_js
raise "couldn't find trufflejs.jar - download GraalVM as described in https://github.com/jruby/jruby/wiki/Downloading-GraalVM and find it in there"
end

def self.find_sl
jar = ENV['SL_JAR']
return jar if jar
raise "couldn't find truffle-sl.jar - build Truffle and find it in there"
end

def self.find_sulong_dir
dir = ENV['SULONG_DIR']
return dir if dir
@@ -350,6 +356,7 @@ def help
puts ' JVMCI_DIR JMVCI repository checkout to use when running IGV (mx must already be on the $PATH)'
puts ' JVMCI_DIR_...git_branch_name... JMVCI repository to use for a given branch'
puts ' GRAAL_JS_JAR The location of trufflejs.jar'
puts ' SL_JAR The location of truffle-sl.jar'
puts ' SULONG_DIR The location of a built checkout of the Sulong repository'
puts ' SULONG_CLASSPATH An explicit classpath to use for Sulong, rather than working it out from SULONG_DIR'
end
@@ -571,6 +578,17 @@ def test_integration(env={}, *args)
jruby_opts = []

jruby_opts << '-Xtruffle.graal.warn_unless=false'

if ENV['GRAAL_JS_JAR']
jruby_opts << '-J-classpath'
jruby_opts << Utilities.find_graal_js
end

if ENV['SL_JAR']
jruby_opts << '-J-classpath'
jruby_opts << Utilities.find_sl
end

env_vars["JRUBY_OPTS"] = jruby_opts.join(' ')

env_vars["PATH"] = "#{Utilities.find_jruby_bin_dir}:#{ENV["PATH"]}"
@@ -659,7 +677,7 @@ def test_specs(command, *args)
private :test_specs

def test_tck(*args)
mvn *args + ['test']
mvn *args + ["-DargLine='-Djruby.home=#{JRUBY_DIR}'", 'test']
end
private :test_tck

2 changes: 2 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/RubyContext.java
Original file line number Diff line number Diff line change
@@ -172,6 +172,8 @@ public RubyContext(Ruby jrubyRuntime, TruffleLanguage.Env env) {
attachmentsManager = new AttachmentsManager(this, instrumenter);
traceManager = new TraceManager(this, instrumenter);
coverageManager = new CoverageManager(this, instrumenter);

coreLibrary.initializePostBoot();
}

public Object send(Object object, String methodName, DynamicObject block, Object... arguments) {
23 changes: 23 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/core/CoreLibrary.java
Original file line number Diff line number Diff line change
@@ -911,6 +911,29 @@ public void initializeAfterBasicMethodsAdded() {
assert Layouts.CLASS.isClass(eagainWaitWritable);
}

public void initializePostBoot() {
if (context.getOptions().PLATFORM_SAFE_LOAD) {
// Load code that can't be run until everything else is boostrapped, such as pre-loaded Ruby stdlib.

try {
Main.printTruffleTimeMetric("before-post-boot");
try {
final RubyRootNode rootNode = context.getCodeLoader().parse(context.getSourceCache().getSource(getCoreLoadPath() + "/core/post-boot.rb"), UTF8Encoding.INSTANCE, ParserContext.TOP_LEVEL, null, true, node);
final CodeLoader.DeferredCall deferredCall = context.getCodeLoader().prepareExecute(ParserContext.TOP_LEVEL, DeclarationContext.TOP_LEVEL, rootNode, null, context.getCoreLibrary().getMainObject());
deferredCall.callWithoutCallNode();
} catch (IOException e) {
throw new RuntimeException(e);
}

Main.printTruffleTimeMetric("after-post-boot");
} catch (RaiseException e) {
final DynamicObject rubyException = e.getException();
BacktraceFormatter.createDefaultFormatter(getContext()).printBacktrace(context, rubyException, Layouts.EXCEPTION.getBacktrace(rubyException));
throw new TruffleFatalException("couldn't load the post-boot code", e);
}
}
}

private void initializeRubiniusFFI() {
Layouts.MODULE.getFields(rubiniusFFIModule).setConstant(context, node, "TYPE_CHAR", RubiniusTypes.TYPE_CHAR);
Layouts.MODULE.getFields(rubiniusFFIModule).setConstant(context, node, "TYPE_UCHAR", RubiniusTypes.TYPE_UCHAR);
Original file line number Diff line number Diff line change
@@ -39,10 +39,13 @@

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.Fallback;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.api.profiles.ConditionProfile;
import com.oracle.truffle.api.source.SourceSection;
import jnr.constants.platform.Sysconf;
import jnr.posix.Passwd;
@@ -62,7 +65,6 @@
import org.jruby.truffle.core.string.StringOperations;
import org.jruby.truffle.core.thread.ThreadManager;
import org.jruby.truffle.language.RubyGuards;
import org.jruby.truffle.language.RubyNode;
import org.jruby.truffle.language.control.ExitException;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.language.control.ThrowException;
@@ -78,12 +80,10 @@
import org.jruby.truffle.platform.signal.SignalHandler;
import org.jruby.truffle.platform.signal.SignalManager;
import org.jruby.util.io.PosixShim;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.util.ArrayList;
import java.util.List;

import static jnr.constants.platform.Errno.ECHILD;
import static jnr.constants.platform.Errno.EINTR;
import static jnr.constants.platform.WaitFlags.WNOHANG;
@@ -110,13 +110,14 @@ private boolean areSame(VirtualFrame frame, Object left, Object right) {
}

@Specialization
public Object doCatch(VirtualFrame frame, Object tag, DynamicObject block) {
CompilerDirectives.transferToInterpreter();

public Object doCatch(VirtualFrame frame, Object tag, DynamicObject block,
@Cached("create()") BranchProfile catchProfile,
@Cached("createBinaryProfile()") ConditionProfile matchProfile) {
try {
return dispatchNode.dispatch(frame, block, tag);
} catch (ThrowException e) {
if (areSame(frame, e.getTag(), tag)) {
catchProfile.enter();
if (matchProfile.profile(areSame(frame, e.getTag(), tag))) {
return e.getValue();
} else {
throw e;
@@ -196,9 +197,9 @@ public DynamicObject vmGetModuleName(DynamicObject module) {
@Primitive(name = "vm_get_user_home", needsSelf = false, unsafe = UnsafeGroup.IO)
public abstract static class VMGetUserHomePrimitiveNode extends PrimitiveArrayArgumentsNode {

@TruffleBoundary
@Specialization(guards = "isRubyString(username)")
public DynamicObject vmGetUserHome(DynamicObject username) {
CompilerDirectives.transferToInterpreter();
// TODO BJF 30-APR-2015 Review the more robust getHomeDirectoryPath implementation
final Passwd passwd = posix().getpwnam(username.toString());
if (passwd == null) {
Original file line number Diff line number Diff line change
@@ -924,8 +924,8 @@ public abstract static class InitializeNode extends YieldingCoreMethodNode {
@Child private ToIntNode toIntNode;
@Child private CallDispatchHeadNode toAryNode;
@Child private KernelNodes.RespondToNode respondToToAryNode;
public abstract DynamicObject executeInitialize(VirtualFrame frame, DynamicObject array, Object size, Object value, Object block);

public abstract DynamicObject executeInitialize(VirtualFrame frame, DynamicObject array, Object size, Object defaultValue, Object block);

@Specialization
public DynamicObject initializeNoArgs(DynamicObject array, NotProvided size, NotProvided unusedValue, NotProvided block) {
Original file line number Diff line number Diff line change
@@ -209,15 +209,11 @@ public InstanceExecNode(RubyContext context, SourceSection sourceSection) {

@Specialization
public Object instanceExec(VirtualFrame frame, Object receiver, Object[] arguments, DynamicObject block) {
CompilerDirectives.transferToInterpreter();

return yield.dispatchWithModifiedSelf(frame, block, receiver, arguments);
}

@Specialization
public Object instanceExec(Object receiver, Object[] arguments, NotProvided block) {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(coreExceptions().localJumpError("no block given", this));
}

@@ -254,7 +250,6 @@ public abstract static class MethodMissingNode extends CoreMethodArrayArgumentsN

@Specialization
public Object methodMissingNoName(Object self, NotProvided name, Object[] args, NotProvided block) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(coreExceptions().argumentError("no id given", this));
}

@@ -268,18 +263,22 @@ public Object methodMissingBlock(Object self, DynamicObject name, Object[] args,
return methodMissing(self, name, args, block);
}

@TruffleBoundary
private Object methodMissing(Object self, DynamicObject nameObject, Object[] args, DynamicObject block) {
throw new RaiseException(buildMethodMissingException(self, nameObject, args, block));
}

@TruffleBoundary
private DynamicObject buildMethodMissingException(Object self, DynamicObject nameObject, Object[] args, DynamicObject block) {
final String name = nameObject.toString();

if (lastCallWasSuper()) {
throw new RaiseException(coreExceptions().noSuperMethodError(name, this));
return coreExceptions().noSuperMethodError(name, this);
} else if (lastCallWasCallingPrivateMethod(self, name)) {
throw new RaiseException(coreExceptions().privateMethodError(name, self, this));
return coreExceptions().privateMethodError(name, self, this);
} else if (lastCallWasVCall()) {
throw new RaiseException(coreExceptions().nameErrorUndefinedLocalVariableOrMethod(name, self, this));
return coreExceptions().nameErrorUndefinedLocalVariableOrMethod(name, self, this);
} else {
throw new RaiseException(coreExceptions().noMethodErrorOnReceiver(name, self, this));
return coreExceptions().noMethodErrorOnReceiver(name, self, this);
}
}

Original file line number Diff line number Diff line change
@@ -10,11 +10,11 @@

package org.jruby.truffle.core.cast;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.Layouts;
import org.jruby.truffle.RubyContext;
@@ -33,6 +33,8 @@ public abstract class NameToJavaStringNode extends RubyNode {

@Child private CallDispatchHeadNode toStr;

private final BranchProfile errorProfile = BranchProfile.create();

public NameToJavaStringNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
toStr = DispatchHeadNodeFactory.createMethodCall(context);
@@ -61,8 +63,8 @@ public String coerceObject(VirtualFrame frame, Object object) {
try {
coerced = toStr.call(frame, object, "to_str", null);
} catch (RaiseException e) {
errorProfile.enter();
if (Layouts.BASIC_OBJECT.getLogicalClass(e.getException()) == coreLibrary().getNoMethodErrorClass()) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(coreExceptions().typeErrorNoImplicitConversion(object, "String", this));
} else {
throw e;
@@ -72,7 +74,7 @@ public String coerceObject(VirtualFrame frame, Object object) {
if (RubyGuards.isRubyString(coerced)) {
return coerced.toString();
} else {
CompilerDirectives.transferToInterpreter();
errorProfile.enter();
throw new RaiseException(coreExceptions().typeErrorBadCoercion(object, "String", "to_str", coerced, this));
}
}
Loading

0 comments on commit 279e0bd

Please sign in to comment.