Skip to content

Commit

Permalink
Showing 37 changed files with 229 additions and 228 deletions.
14 changes: 4 additions & 10 deletions core/src/main/java/org/jruby/RubyKernel.java
Original file line number Diff line number Diff line change
@@ -1129,6 +1129,8 @@ public static IRubyObject rbThrow19(ThreadContext context, IRubyObject recv, IRu
return rbThrowInternal(context, tag, value);
}

private static final byte[] uncaught_throw_p = { 'u','n','c','a','u','g','h','t',' ','t','h','r','o','w',' ','%','p' };

private static IRubyObject rbThrowInternal(ThreadContext context, IRubyObject tag, IRubyObject arg) {
final Ruby runtime = context.runtime;
runtime.getGlobalVariables().set("$!", context.nil);
@@ -1142,13 +1144,7 @@ private static IRubyObject rbThrowInternal(ThreadContext context, IRubyObject ta

// No catch active for this throw
IRubyObject value = arg == null ? context.nil : arg;
String message = "uncaught throw %p";

final RubyThread currentThread = context.getThread();
if (currentThread != runtime.getThreadService().getMainThread()) {
message += " in thread 0x" + Integer.toHexString(System.identityHashCode(currentThread.getNativeThread()));
}
throw uncaughtThrow(runtime, tag, value, runtime.newString(message));
throw uncaughtThrow(runtime, tag, value, RubyString.newStringShared(runtime, uncaught_throw_p));
}

private static RaiseException uncaughtThrow(Ruby runtime, IRubyObject tag, IRubyObject value, RubyString message) {
@@ -1478,9 +1474,7 @@ public static IRubyObject backquote(ThreadContext context, IRubyObject recv, IRu
length = newPos;
}
ByteList buf = new ByteList(out, 0, length, runtime.getDefaultExternalEncoding(), false);
RubyString newString = RubyString.newString(runtime, buf);

return newString;
return RubyString.newString(runtime, buf);
}

@JRubyMethod(module = true, visibility = PRIVATE)
4 changes: 2 additions & 2 deletions samples/truffle/interop/weather/weather.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Interop.eval('application/x-ruby', 'require "weather"');

temperature_in_city = Interop.import('temperature_in_city')
Weather = Interop.import('weather')

console.log('Temperature in New York now: ' + temperature_in_city.call('New York') + '℃');
console.log('Temperature in New York now: ' + Weather.temperature_in_city('New York') + '℃');
12 changes: 7 additions & 5 deletions samples/truffle/interop/weather/weather.rb
Original file line number Diff line number Diff line change
@@ -6,10 +6,12 @@
config.apikey = 'dd7073d18e3085d0300b6678615d904d'
end

def temperature_in_city(name)
name = Truffle::Interop.from_java_string(name)
weather = Openweather2.get_weather(city: name, units: 'metric')
weather.temperature
module Weather
def self.temperature_in_city(name)
name = Truffle::Interop.from_java_string(name)
weather = Openweather2.get_weather(city: name, units: 'metric')
weather.temperature
end
end

Truffle::Interop.export_method :temperature_in_city
Truffle::Interop.export :weather, Weather
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/encoding/converter/last_error_tags.txt

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
fails:Encoding::InvalidByteSequenceError#error_bytes returns a String
fails:Encoding::InvalidByteSequenceError#error_bytes returns the bytes that caused the exception
fails:Encoding::InvalidByteSequenceError#error_bytes uses ASCII-8BIT as the encoding

This file was deleted.

This file was deleted.

8 changes: 5 additions & 3 deletions tool/jruby_eclipse
Original file line number Diff line number Diff line change
@@ -2,9 +2,13 @@
# A JRuby launcher, in Ruby, and using the class files from Eclipse
# Currently needs the core and stdlib jar, so build them again when they change.

JRUBY = File.expand_path('../..', __FILE__)

M2REPO = "#{Dir.home}/.m2/repository"

TRUFFLE_VERSION = "0.13"
TRUFFLE_VERSION = File.foreach("#{JRUBY}/truffle/pom.rb") { |line|
break $1 if /'truffle\.version' => '(\d+\.\d+|\h+-SNAPSHOT)'/ =~ line
}

TRUFFLEJARS = %W[
com/oracle/truffle/truffle-api/#{TRUFFLE_VERSION}/truffle-api-#{TRUFFLE_VERSION}.jar
@@ -17,8 +21,6 @@ JLINE = "#{M2REPO}/jline/jline/2.11/jline-2.11.jar"

GRAAL_OPTIONS_PREFIX = "graal."

JRUBY = File.expand_path('../..', __FILE__)

VERIFY_JRUBY = false

java = ENV["JAVACMD"] || "java"
25 changes: 15 additions & 10 deletions truffle/src/main/java/org/jruby/truffle/builtins/CoreMethod.java
Original file line number Diff line number Diff line change
@@ -55,24 +55,29 @@

boolean needsBlock() default false;

boolean lowerFixnumSelf() default false;

int[] lowerFixnumParameters() default {};

boolean taintFromSelf() default false;

int taintFromParameter() default -1;
/**
* Try to lower argument <code>i</code> (starting at 1) to an int if its value is a long.
* Use 0 for <code>self</code>.
*/
int[] lowerFixnum() default {};

/**
* Raise an error if self is frozen.
*/
boolean raiseIfFrozenSelf() default false;

int[] raiseIfFrozenParameters() default {};
/**
* Taint the result if argument <code>i</code> (starting at 1) is tainted.
* Use 0 for <code>self</code>.
*/
int taintFrom() default -1;

UnsupportedOperationBehavior unsupportedOperationBehavior() default UnsupportedOperationBehavior.TYPE_ERROR;

boolean returnsEnumeratorIfNoBlock() default false;

UnsafeGroup[] unsafe() default {};

String enumeratorSize() default "";

UnsafeGroup[] unsafe() default {};

}
Original file line number Diff line number Diff line change
@@ -188,32 +188,14 @@ private static CallTarget makeGenericMethod(RubyContext context, MethodDetails m

if (needsSelf) {
RubyNode readSelfNode = new SelfNode(context, sourceSection);

if (method.lowerFixnumSelf()) {
readSelfNode = FixnumLowerNodeGen.create(context, sourceSection, readSelfNode);
}

if (method.raiseIfFrozenSelf()) {
readSelfNode = new RaiseIfFrozenNode(readSelfNode);
}

argumentsNodes.add(readSelfNode);
argumentsNodes.add(transformArgument(method, readSelfNode, 0));
}

final int nArgs = required + optional;

for (int n = 0; n < nArgs; n++) {
RubyNode readArgumentNode = new ReadPreArgumentNode(n, MissingArgumentBehavior.UNDEFINED);

if (ArrayUtils.contains(method.lowerFixnumParameters(), n)) {
readArgumentNode = FixnumLowerNodeGen.create(context, sourceSection, readArgumentNode);
}

if (ArrayUtils.contains(method.raiseIfFrozenParameters(), n)) {
readArgumentNode = new RaiseIfFrozenNode(readArgumentNode);
}

argumentsNodes.add(readArgumentNode);
argumentsNodes.add(transformArgument(method, readArgumentNode, n + 1));
}
if (method.rest()) {
argumentsNodes.add(new ReadRemainingArgumentsNode(nArgs));
@@ -256,35 +238,50 @@ private static CallTarget makeGenericMethod(RubyContext context, MethodDetails m

final RubyNode checkArity = Translator.createCheckArityNode(context, sourceSection, sharedMethodInfo.getArity());

RubyNode sequence;

RubyNode node;
if (!isSafe(context, method.unsafe())) {
sequence = new UnsafeNode(context, sourceSection);
node = new UnsafeNode(context, sourceSection);
} else {
sequence = Translator.sequence(context, sourceSection, Arrays.asList(checkArity, methodNode));
node = Translator.sequence(context, sourceSection, Arrays.asList(checkArity, methodNode));
node = transformResult(method, node);
}

final ExceptionTranslatingNode exceptionTranslatingNode = new ExceptionTranslatingNode(context, sourceSection, node, method.unsupportedOperationBehavior());

if (!method.enumeratorSize().isEmpty()) {
assert !method.returnsEnumeratorIfNoBlock(): "Only one of enumeratorSize or returnsEnumeratorIfNoBlock can be specified";
// TODO BF 6-27-2015 Handle multiple method names correctly
sequence = new EnumeratorSizeNode(method.enumeratorSize(), method.names()[0], sequence);
} else if (method.returnsEnumeratorIfNoBlock()) {
// TODO BF 3-18-2015 Handle multiple method names correctly
sequence = new ReturnEnumeratorIfNoBlockNode(method.names()[0], sequence);
}
final RubyRootNode rootNode = new RubyRootNode(context, sourceSection, null, sharedMethodInfo, exceptionTranslatingNode, false);

if (method.taintFromSelf() || method.taintFromParameter() != -1) {
sequence = new TaintResultNode(method.taintFromSelf(),
method.taintFromParameter(),
sequence);
}
return Truffle.getRuntime().createCallTarget(rootNode);
}

private static RubyNode transformArgument(CoreMethod method, RubyNode argument, int n) {
if (ArrayUtils.contains(method.lowerFixnum(), n)) {
argument = FixnumLowerNodeGen.create(null, null, argument);
}

final ExceptionTranslatingNode exceptionTranslatingNode = new ExceptionTranslatingNode(context, sourceSection, sequence, method.unsupportedOperationBehavior());
if (n == 0 && method.raiseIfFrozenSelf()) {
argument = new RaiseIfFrozenNode(argument);
}

final RubyRootNode rootNode = new RubyRootNode(context, sourceSection, null, sharedMethodInfo, exceptionTranslatingNode, false);
return argument;
}

return Truffle.getRuntime().createCallTarget(rootNode);
private static RubyNode transformResult(CoreMethod method, RubyNode node) {
if (!method.enumeratorSize().isEmpty()) {
assert !method.returnsEnumeratorIfNoBlock(): "Only one of enumeratorSize or returnsEnumeratorIfNoBlock can be specified";
// TODO BF 6-27-2015 Handle multiple method names correctly
node = new EnumeratorSizeNode(method.enumeratorSize(), method.names()[0], node);
} else if (method.returnsEnumeratorIfNoBlock()) {
// TODO BF 3-18-2015 Handle multiple method names correctly
node = new ReturnEnumeratorIfNoBlockNode(method.names()[0], node);
}

if (method.taintFrom() != -1) {
final boolean taintFromSelf = method.taintFrom() == 0;
final int taintFromArg = taintFromSelf ? -1 : method.taintFrom() - 1;
node = new TaintResultNode(taintFromSelf, taintFromArg, node);
}

return node;
}

public static boolean isSafe(RubyContext context, UnsafeGroup[] groups) {
38 changes: 17 additions & 21 deletions truffle/src/main/java/org/jruby/truffle/core/array/ArrayNodes.java
Original file line number Diff line number Diff line change
@@ -183,7 +183,7 @@ public DynamicObject addGeneralize(DynamicObject a, DynamicObject b,

}

@CoreMethod(names = "*", required = 1, lowerFixnumParameters = 0, taintFromSelf = true)
@CoreMethod(names = "*", required = 1, lowerFixnum = 1, taintFrom = 0)
public abstract static class MulNode extends ArrayCoreMethodNode {

@Child private KernelNodes.RespondToNode respondToToStrNode;
@@ -263,7 +263,7 @@ public boolean respondToToStr(VirtualFrame frame, Object object) {

}

@CoreMethod(names = { "[]", "slice" }, required = 1, optional = 1, lowerFixnumParameters = { 0, 1 })
@CoreMethod(names = { "[]", "slice" }, required = 1, optional = 1, lowerFixnum = { 1, 2 })
public abstract static class IndexNode extends ArrayCoreMethodNode {

@Child protected ArrayReadDenormalizedNode readNode;
@@ -353,7 +353,7 @@ public Object fallback(VirtualFrame frame, DynamicObject array, DynamicObject ar

}

@CoreMethod(names = "[]=", required = 2, optional = 1, lowerFixnumParameters = 0, raiseIfFrozenSelf = true)
@CoreMethod(names = "[]=", required = 2, optional = 1, lowerFixnum = 1, raiseIfFrozenSelf = true)
public abstract static class IndexSetNode extends ArrayCoreMethodNode {

@Child private ArrayReadNormalizedNode readNode;
@@ -723,40 +723,36 @@ public Object delete(VirtualFrame frame, DynamicObject array, Object value, Obje
final ArrayMirror store = strategy.newMirror(array);

Object found = nil();
boolean isFound = false;

int i = 0;
int n = 0;
for (; n < getSize(array); n++) {
while (n < getSize(array)) {
final Object stored = store.get(n);

if (equalNode.executeSameOrEqual(frame, stored, value)) {
checkFrozen(array);
found = stored;
isFound = true;
continue;
}
n++;
} else {
if (i != n) {
store.set(i, store.get(n));
}

if (i != n) {
store.set(i, store.get(n));
i++;
n++;
}

i++;
}

if (i != n) {
setStoreAndSize(array, store.getArray(), i);
}

if(!isFound){
return found;
} else {
if (maybeBlock == NotProvided.INSTANCE) {
return nil();
} else {
return yield(frame, (DynamicObject) maybeBlock, value);
}
}

return found;
}

public void checkFrozen(Object object) {
@@ -769,7 +765,7 @@ public void checkFrozen(Object object) {

}

@CoreMethod(names = "delete_at", required = 1, raiseIfFrozenSelf = true, lowerFixnumParameters = 0)
@CoreMethod(names = "delete_at", required = 1, raiseIfFrozenSelf = true, lowerFixnum = 1)
@NodeChildren({
@NodeChild(type = RubyNode.class, value = "array"),
@NodeChild(type = RubyNode.class, value = "index")
@@ -941,7 +937,7 @@ public boolean include(VirtualFrame frame, DynamicObject array, Object value,

}

@CoreMethod(names = "initialize", needsBlock = true, optional = 2, raiseIfFrozenSelf = true, lowerFixnumParameters = 0)
@CoreMethod(names = "initialize", needsBlock = true, optional = 2, raiseIfFrozenSelf = true, lowerFixnum = 1)
@ImportStatic(ArrayGuards.class)
public abstract static class InitializeNode extends YieldingCoreMethodNode {

@@ -1530,7 +1526,7 @@ public CallTarget getCallTarget() {
}
}

@CoreMethod(names = "pack", required = 1, taintFromParameter = 0)
@CoreMethod(names = "pack", required = 1, taintFrom = 1)
@ImportStatic(StringCachingGuards.class)
public abstract static class PackNode extends ArrayCoreMethodNode {

@@ -1798,7 +1794,7 @@ public Object rejectOther(VirtualFrame frame, DynamicObject array, DynamicObject

}

@CoreMethod(names = "delete_if" , needsBlock = true, enumeratorSize = "size", raiseIfFrozenSelf = true)
@CoreMethod(names = "delete_if", needsBlock = true, enumeratorSize = "size", raiseIfFrozenSelf = true)
@ImportStatic(ArrayGuards.class)
public abstract static class DeleteIfNode extends YieldingCoreMethodNode {

Original file line number Diff line number Diff line change
@@ -80,15 +80,17 @@ public Object execute(VirtualFrame frame) {
maybeTaint((DynamicObject) RubyArguments.getSelf(frame), result);
}

// It's possible the taintFromParameter value was misconfigured by the user, but the far more likely
// scenario is that the argument at that position is a NotProvided argument, which doesn't take up
// a space in the frame.
if (taintFromParameter < RubyArguments.getArgumentsCount(frame)) {
final Object argument = RubyArguments.getArgument(frame, taintFromParameter);

if (argument instanceof DynamicObject) {
final DynamicObject taintSource = (DynamicObject) argument;
maybeTaint(taintSource, result);
if (taintFromParameter != -1) {
// It's possible the taintFromParameter value was misconfigured by the user, but the far more likely
// scenario is that the argument at that position is a NotProvided argument, which doesn't take up
// a space in the frame.
if (taintFromParameter < RubyArguments.getArgumentsCount(frame)) {
final Object argument = RubyArguments.getArgument(frame, taintFromParameter);

if (argument instanceof DynamicObject) {
final DynamicObject taintSource = (DynamicObject) argument;
maybeTaint(taintSource, result);
}
}
}
}
Loading

0 comments on commit 373e5dc

Please sign in to comment.