Skip to content

Commit

Permalink
Showing 197 changed files with 2,287 additions and 648 deletions.
27 changes: 14 additions & 13 deletions core/src/main/java/org/jruby/ext/digest/BubbleBabble.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.jruby.ext.digest;

import org.jruby.util.ByteList;

/**
* Ported from OpenSSH (https://github.com/openssh/openssh-portable/blob/957fbceb0f3166e41b76fdb54075ab3b9cc84cba/sshkey.c#L942-L987)
*
@@ -32,42 +34,41 @@

public class BubbleBabble {

public static String bubblebabble(byte[] digestRaw) {
public static ByteList bubblebabble(byte[] message, int begin, int length) {
char[] vowels = new char[]{'a', 'e', 'i', 'o', 'u', 'y'};
char[] consonants = new char[]{'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
'n', 'p', 'r', 's', 't', 'v', 'z', 'x'};

int seed = 1;

StringBuffer retval = new StringBuffer();
int rawLen = digestRaw.length;
ByteList retval = new ByteList();

int rounds = (rawLen / 2) + 1;
int rounds = (length / 2) + 1;
retval.append('x');
for (int i = 0; i < rounds; i++) {
int idx0, idx1, idx2, idx3, idx4;

if ((i + 1 < rounds) || (rawLen % 2 != 0)) {
idx0 = (((((int) (digestRaw[2 * i])) >> 6) & 3) + seed) % 6;
idx1 = (((int) (digestRaw[2 * i])) >> 2) & 15;
idx2 = ((((int) (digestRaw[2 * i])) & 3) + (seed / 6)) % 6;
if ((i + 1 < rounds) || (length % 2 != 0)) {
idx0 = (((((int) (message[begin + 2 * i])) >> 6) & 3) + seed) % 6;
idx1 = (((int) (message[begin + 2 * i])) >> 2) & 15;
idx2 = ((((int) (message[begin + 2 * i])) & 3) + (seed / 6)) % 6;
retval.append(vowels[idx0]);
retval.append(consonants[idx1]);
retval.append(vowels[idx2]);
if ((i + 1) < rounds) {
idx3 = (((int) (digestRaw[(2 * i) + 1])) >> 4) & 15;
idx4 = (((int) (digestRaw[(2 * i) + 1]))) & 15;
idx3 = (((int) (message[begin + (2 * i) + 1])) >> 4) & 15;
idx4 = (((int) (message[begin + (2 * i) + 1]))) & 15;
retval.append(consonants[idx3]);
retval.append('-');
retval.append(consonants[idx4]);
seed = ((seed * 5) +
((((int) (digestRaw[2 * i])) * 7) +
((int) (digestRaw[(2 * i) + 1])))) % 36;
((((int) (message[begin + 2 * i])) * 7) +
((int) (message[begin + (2 * i) + 1])))) % 36;
}
}
}
retval.append('x');

return retval.toString();
return retval;
}
}
8 changes: 5 additions & 3 deletions core/src/main/java/org/jruby/ext/digest/RubyDigest.java
Original file line number Diff line number Diff line change
@@ -157,7 +157,8 @@ public static IRubyObject s_hexencode(IRubyObject recv, IRubyObject arg) {

@JRubyMethod(name = "bubblebabble", required = 1, meta = true)
public static IRubyObject bubblebabble(IRubyObject recv, IRubyObject arg) {
return RubyString.newString(recv.getRuntime(), BubbleBabble.bubblebabble(arg.convertToString().getBytes()));
final ByteList bytes = arg.convertToString().getByteList();
return RubyString.newString(recv.getRuntime(), BubbleBabble.bubblebabble(bytes.unsafeBytes(), bytes.begin(), bytes.length()));
}

private static class Metadata {
@@ -336,7 +337,7 @@ public static IRubyObject hexdigest_bang(ThreadContext context, IRubyObject self
@JRubyMethod(name = "bubblebabble", required = 1, optional = 1, meta = true)
public static IRubyObject bubblebabble(ThreadContext context, IRubyObject recv, IRubyObject[] args, Block unusedBlock) {
byte[] digest = recv.callMethod(context, "digest", args, Block.NULL_BLOCK).convertToString().getBytes();
return RubyString.newString(recv.getRuntime(), BubbleBabble.bubblebabble(digest));
return RubyString.newString(recv.getRuntime(), BubbleBabble.bubblebabble(digest, 0, digest.length));
}

@JRubyMethod()
@@ -480,7 +481,8 @@ public IRubyObject reset() {

@JRubyMethod()
public IRubyObject bubblebabble(ThreadContext context) {
return RubyString.newString(context.runtime, BubbleBabble.bubblebabble(algo.digest()));
final byte[] digest = algo.digest();
return RubyString.newString(context.runtime, BubbleBabble.bubblebabble(digest, 0, digest.length));
}

private void setAlgorithm(Metadata metadata) throws NoSuchAlgorithmException {
4 changes: 2 additions & 2 deletions core/src/main/java/org/jruby/util/TypeConverter.java
Original file line number Diff line number Diff line change
@@ -293,11 +293,11 @@ public static void checkType(ThreadContext context, IRubyObject x, RubyModule t)
throw context.runtime.newRuntimeError("bug: undef leaked to the Ruby space");
}

xt = x.getMetaClass().getNativeClassIndex();
xt = x.getMetaClass().getClassIndex();

// MISSING: special error for T_DATA of a certain type
if (xt != t.getClassIndex()) {
String tname = t.getBaseName();
String tname = x.getMetaClass().toString();
if (tname != null) {
throw context.runtime.newTypeError("wrong argument type " + tname + " (expected " + t.getName() + ")");
}
9 changes: 9 additions & 0 deletions lib/ruby/truffle/mri/thread.rb
Original file line number Diff line number Diff line change
@@ -373,3 +373,12 @@ def num_waiting

# Documentation comments:
# - How do you make RDoc inherit documentation from superclass?

# Truffle: define marshal_dump as MRI tests expect it
[ConditionVariable, Queue].each do |klass|
klass.class_exec do
def marshal_dump
raise TypeError, "can't dump #{self.class}"
end
end
end
1 change: 1 addition & 0 deletions lib/ruby/truffle/rubysl/README.md
Original file line number Diff line number Diff line change
@@ -11,3 +11,4 @@ Commits for each library are:
* rubysl-pathname `cdf215804c4349353a60226b5c1d71f695d45570`
* rubysl-tempfile `97c4464b4d235f773aab537fbc80608a730a58fc`
* rubysl-socket `3a8c965b36643208da81360ddb4ca7ba867cd3c4`
* rubysl-securerandom `00e31daaf492f7987aa50750dfc3ebc8e8c42a7e`
25 changes: 25 additions & 0 deletions lib/ruby/truffle/rubysl/rubysl-securerandom/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Copyright (c) 2013, Brian Shirai
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the library nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
require "rubysl/securerandom/securerandom"
require "rubysl/securerandom/version"
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
# = Secure random number generator interface.
#
# This library is an interface for secure random number generator which is
# suitable for generating session key in HTTP cookies, etc.
#
# It supports following secure random number generators.
#
# * openssl
# * /dev/urandom
# * Win32
#
# == Example
#
# # random hexadecimal string.
# p SecureRandom.hex(10) #=> "52750b30ffbc7de3b362"
# p SecureRandom.hex(10) #=> "92b15d6c8dc4beb5f559"
# p SecureRandom.hex(11) #=> "6aca1b5c58e4863e6b81b8"
# p SecureRandom.hex(12) #=> "94b2fff3e7fd9b9c391a2306"
# p SecureRandom.hex(13) #=> "39b290146bea6ce975c37cfc23"
# ...
#
# # random base64 string.
# p SecureRandom.base64(10) #=> "EcmTPZwWRAozdA=="
# p SecureRandom.base64(10) #=> "9b0nsevdwNuM/w=="
# p SecureRandom.base64(10) #=> "KO1nIU+p9DKxGg=="
# p SecureRandom.base64(11) #=> "l7XEiFja+8EKEtY="
# p SecureRandom.base64(12) #=> "7kJSM/MzBJI+75j8"
# p SecureRandom.base64(13) #=> "vKLJ0tXBHqQOuIcSIg=="
# ...
#
# # random binary string.
# p SecureRandom.random_bytes(10) #=> "\016\t{\370g\310pbr\301"
# p SecureRandom.random_bytes(10) #=> "\323U\030TO\234\357\020\a\337"
# ...

begin
require 'openssl'
rescue LoadError
end

module SecureRandom
# SecureRandom.random_bytes generates a random binary string.
#
# The argument _n_ specifies the length of the result string.
#
# If _n_ is not specified, 16 is assumed.
# It may be larger in future.
#
# The result may contain any byte: "\x00" - "\xff".
#
# p SecureRandom.random_bytes #=> "\xD8\\\xE0\xF4\r\xB2\xFC*WM\xFF\x83\x18\xF45\xB6"
# p SecureRandom.random_bytes #=> "m\xDC\xFC/\a\x00Uf\xB2\xB2P\xBD\xFF6S\x97"
#
# If secure random number generator is not available,
# NotImplementedError is raised.
def self.random_bytes(n=nil)
n ||= 16

if defined? OpenSSL::Random
@pid = 0 if !defined?(@pid)
pid = $$
if @pid != pid
now = Time.now
ary = [now.to_i, now.nsec, @pid, pid]
OpenSSL::Random.seed(ary.to_s)
@pid = pid
end
return OpenSSL::Random.random_bytes(n)
end

if !defined?(@has_urandom) || @has_urandom
flags = File::RDONLY
flags |= File::NONBLOCK if defined? File::NONBLOCK
flags |= File::NOCTTY if defined? File::NOCTTY
begin
File.open("/dev/urandom", flags) {|f|
unless f.stat.chardev?
raise Errno::ENOENT
end
@has_urandom = true
ret = f.readpartial(n)
if ret.length != n
raise NotImplementedError, "Unexpected partial read from random device"
end
return ret
}
rescue Errno::ENOENT
@has_urandom = false
end
end

if !defined?(@has_win32)
begin
require 'Win32API'

crypt_acquire_context = Win32API.new("advapi32", "CryptAcquireContext", 'PPPII', 'L')
@crypt_gen_random = Win32API.new("advapi32", "CryptGenRandom", 'LIP', 'L')

hProvStr = " " * 4
prov_rsa_full = 1
crypt_verifycontext = 0xF0000000

if crypt_acquire_context.call(hProvStr, nil, nil, prov_rsa_full, crypt_verifycontext) == 0
raise SystemCallError, "CryptAcquireContext failed: #{lastWin32ErrorMessage}"
end
@hProv, = hProvStr.unpack('L')

@has_win32 = true
rescue LoadError
@has_win32 = false
end
end
if @has_win32
bytes = " ".force_encoding("ASCII-8BIT") * n
if @crypt_gen_random.call(@hProv, bytes.size, bytes) == 0
raise SystemCallError, "CryptGenRandom failed: #{lastWin32ErrorMessage}"
end
return bytes
end

raise NotImplementedError, "No random device"
end

# SecureRandom.hex generates a random hex string.
#
# The argument _n_ specifies the length of the random length.
# The length of the result string is twice of _n_.
#
# If _n_ is not specified, 16 is assumed.
# It may be larger in future.
#
# The result may contain 0-9 and a-f.
#
# p SecureRandom.hex #=> "eb693ec8252cd630102fd0d0fb7c3485"
# p SecureRandom.hex #=> "91dc3bfb4de5b11d029d376634589b61"
#
# If secure random number generator is not available,
# NotImplementedError is raised.
def self.hex(n=nil)
random_bytes(n).unpack("H*")[0]
end

# SecureRandom.base64 generates a random base64 string.
#
# The argument _n_ specifies the length of the random length.
# The length of the result string is about 4/3 of _n_.
#
# If _n_ is not specified, 16 is assumed.
# It may be larger in future.
#
# The result may contain A-Z, a-z, 0-9, "+", "/" and "=".
#
# p SecureRandom.base64 #=> "/2BuBuLf3+WfSKyQbRcc/A=="
# p SecureRandom.base64 #=> "6BbW0pxO0YENxn38HMUbcQ=="
#
# If secure random number generator is not available,
# NotImplementedError is raised.
#
# See RFC 3548 for the definition of base64.
def self.base64(n=nil)
[random_bytes(n)].pack("m*").delete("\n")
end

# SecureRandom.urlsafe_base64 generates a random URL-safe base64 string.
#
# The argument _n_ specifies the length of the random length.
# The length of the result string is about 4/3 of _n_.
#
# If _n_ is not specified, 16 is assumed.
# It may be larger in future.
#
# The boolean argument _padding_ specifies the padding.
# If it is false or nil, padding is not generated.
# Otherwise padding is generated.
# By default, padding is not generated because "=" may be used as a URL delimiter.
#
# The result may contain A-Z, a-z, 0-9, "-" and "_".
# "=" is also used if _padding_ is true.
#
# p SecureRandom.urlsafe_base64 #=> "b4GOKm4pOYU_-BOXcrUGDg"
# p SecureRandom.urlsafe_base64 #=> "UZLdOkzop70Ddx-IJR0ABg"
#
# p SecureRandom.urlsafe_base64(nil, true) #=> "i0XQ-7gglIsHGV2_BNPrdQ=="
# p SecureRandom.urlsafe_base64(nil, true) #=> "-M8rLhr7JEpJlqFGUMmOxg=="
#
# If secure random number generator is not available,
# NotImplementedError is raised.
#
# See RFC 3548 for the definition of URL-safe base64.
def self.urlsafe_base64(n=nil, padding=false)
s = [random_bytes(n)].pack("m*")
s.delete!("\n")
s.tr!("+/", "-_")
s.delete!("=") if !padding
s
end

# SecureRandom.random_number generates a random number.
#
# If a positive integer is given as _n_,
# SecureRandom.random_number returns an integer:
# 0 <= SecureRandom.random_number(n) < n.
#
# p SecureRandom.random_number(100) #=> 15
# p SecureRandom.random_number(100) #=> 88
#
# If 0 is given or an argument is not given,
# SecureRandom.random_number returns a float:
# 0.0 <= SecureRandom.random_number() < 1.0.
#
# p SecureRandom.random_number #=> 0.596506046187744
# p SecureRandom.random_number #=> 0.350621695741409
#
def self.random_number(n=0)
if 0 < n
hex = n.to_s(16)
hex = '0' + hex if (hex.length & 1) == 1
bin = [hex].pack("H*")
mask = bin[0].ord
mask |= mask >> 1
mask |= mask >> 2
mask |= mask >> 4
begin
rnd = SecureRandom.random_bytes(bin.length)
rnd[0] = (rnd[0].ord & mask).chr
end until rnd < bin
rnd.unpack("H*")[0].hex
else
# assumption: Float::MANT_DIG <= 64
i64 = SecureRandom.random_bytes(8).unpack("Q")[0]
Math.ldexp(i64 >> (64-Float::MANT_DIG), -Float::MANT_DIG)
end
end

# SecureRandom.uuid generates a v4 random UUID (Universally Unique IDentifier).
#
# p SecureRandom.uuid #=> "2d931510-d99f-494a-8c67-87feb05e1594"
# p SecureRandom.uuid #=> "bad85eb9-0713-4da7-8d36-07a8e4b00eab"
# p SecureRandom.uuid #=> "62936e70-1815-439b-bf89-8492855a7e6b"
#
# The version 4 UUID is purely random (except the version).
# It doesn't contain meaningful information such as MAC address, time, etc.
#
# See RFC 4122 for details of UUID.
#
def self.uuid
ary = self.random_bytes(16).unpack("NnnnnN")
ary[2] = (ary[2] & 0x0fff) | 0x4000
ary[3] = (ary[3] & 0x3fff) | 0x8000
"%08x-%04x-%04x-%04x-%04x%08x" % ary
end

# Following code is based on David Garamond's GUID library for Ruby.
def self.lastWin32ErrorMessage # :nodoc:
get_last_error = Win32API.new("kernel32", "GetLastError", '', 'L')
format_message = Win32API.new("kernel32", "FormatMessageA", 'LPLLPLPPPPPPPP', 'L')
format_message_ignore_inserts = 0x00000200
format_message_from_system = 0x00001000

code = get_last_error.call
msg = "\0" * 1024
len = format_message.call(format_message_ignore_inserts + format_message_from_system, 0, code, 0, msg, 1024, nil, nil, nil, nil, nil, nil, nil, nil)
msg[0, len].tr("\r", '').chomp
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module RubySL
module SecureRandom
VERSION = "2.0.0"
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require "rubysl/securerandom"
9 changes: 9 additions & 0 deletions lib/ruby/truffle/truffle/bigdecimal.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# TODO require bigdecimal/*

BigDecimal = Truffle::BigDecimal

module Kernel
def BigDecimal(*args)
BigDecimal.new *args
end
end
153 changes: 153 additions & 0 deletions lib/ruby/truffle/truffle/digest.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# Copyright (c) 2015 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

module Digest

NO_MESSAGE = Object.new

class Algorithm

def self.file(file)
digest = new
digest.update File.read(file)
digest
end

def self.digest(message)
digest = new
digest.update message
digest.digest
end

def self.hexdigest(message)
digest = new
digest.update message
digest.hexdigest
end

def update(message)
Truffle::Digest.update @digest, message
end

alias_method :<<, :update

def reset
Truffle::Digest.reset @digest
end

def digest(message=NO_MESSAGE)
if NO_MESSAGE == message
Truffle::Digest.digest @digest
else
reset
update message
digest!
end
end

def hexdigest(message=NO_MESSAGE)
Digest.hexencode(digest(message))
end

alias_method :to_s, :hexdigest
alias_method :to_str, :hexdigest

def digest!
digested = digest
reset
digested
end

def hexdigest!
digested = hexdigest
reset
digested
end

def digest_length
Truffle::Digest.digest_length @digest
end

alias_method :size, :digest_length
alias_method :length, :digest_length

def ==(other)
hexdigest == other.to_str
end

def inspect
"#<#{self.class.name}: #{hexdigest}>"
end

end

class MD5 < Algorithm

def initialize
@digest = Truffle::Digest.md5
end

def block_length
64
end

end

class SHA1 < Algorithm

def initialize
@digest = Truffle::Digest.sha1
end

def block_length
64
end

end

class SHA256 < Algorithm

def initialize
@digest = Truffle::Digest.sha256
end

def block_length
64
end

end

class SHA384 < Algorithm

def initialize
@digest = Truffle::Digest.sha384
end

def block_length
128
end

end

class SHA512 < Algorithm

def initialize
@digest = Truffle::Digest.sha512
end

def block_length
128
end

end

def self.hexencode(message)
StringValue(message).unpack('H*').first
end

end
31 changes: 31 additions & 0 deletions lib/ruby/truffle/truffle/digest/bubblebabble.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright (c) 2015 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

require 'digest'

module Digest

def self.bubblebabble(message)
Truffle::Digest.bubblebabble(StringValue(message))
end

class Algorithm

def self.bubblebabble(message)
digest = new
digest.update message
digest.bubblebabble
end

def bubblebabble(message=NO_MESSAGE)
Digest.bubblebabble(digest(message))
end

end

end
1 change: 1 addition & 0 deletions lib/ruby/truffle/truffle/digest/md5.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require 'digest'
1 change: 1 addition & 0 deletions lib/ruby/truffle/truffle/digest/rmd160.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require 'digest'
1 change: 1 addition & 0 deletions lib/ruby/truffle/truffle/digest/sha1.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require 'digest'
1 change: 1 addition & 0 deletions lib/ruby/truffle/truffle/digest/sha2.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require 'digest'
36 changes: 36 additions & 0 deletions lib/ruby/truffle/truffle/zlib.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright (c) 2015 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

module Zlib

NO_COMPRESSION = 0
BEST_SPEED = 1
BEST_COMPRESSION = 9
DEFAULT_COMPRESSION = -1

def self.crc32(*args)
Truffle::Zlib.crc32(*args)
end

module Deflate

def self.deflate(message, level=DEFAULT_COMPRESSION)
Truffle::Zlib.deflate(message, level)
end

end

module Inflate

def self.inflate(message)
Truffle::Zlib.inflate(message)
end

end

end
5 changes: 4 additions & 1 deletion spec/jruby.2.2.mspec
Original file line number Diff line number Diff line change
@@ -73,7 +73,10 @@ class MSpecScript
'^' + SPEC_DIR + '/library/syslog',

# masked out because of load-time errors that can't be tagged
'^' + SPEC_DIR + '/library/net/http'
'^' + SPEC_DIR + '/library/net/http',

# Module not available
'^' + SPEC_DIR + '/library/digest/bubblebabble'
]

# Command Line specs
67 changes: 67 additions & 0 deletions spec/ruby/language/fixtures/super.rb
Original file line number Diff line number Diff line change
@@ -370,4 +370,71 @@ def a
end
end

module ZSuperWithOptional
class A
def m(x, y, z)
z
end
end

class B < A
def m(x, y, z = 14)
super
end
end

class C < A
def m(x, y, z = 14)
z = 100
super
end
end
end

module ZSuperWithRest
class A
def m(*args)
args
end

def m_modified(*args)
args
end
end

class B < A
def m(*args)
super
end

def m_modified(*args)
args[1] = 14
super
end
end
end

module ZSuperWithRestAndOthers
class A
def m(a, b, *args)
args
end

def m_modified(a, b, *args)
args
end
end

class B < A
def m(a, b, *args)
super
end

def m_modified(a, b, *args)
args[1] = 14
super
end
end
end

end
34 changes: 33 additions & 1 deletion spec/ruby/language/super_spec.rb
Original file line number Diff line number Diff line change
@@ -162,8 +162,40 @@ def a(arg)
Super::AnonymousModuleIncludedTwice.new.a([]).should == ["anon", "anon", "non-anon"]
end

it "can accept a block but still pass the original arguments" do
it "without explicit arguments can accept a block but still pass the original arguments" do
Super::ZSuperWithBlock::B.new.a.should == 14
end

it "without explicit arguments passes optional arguments that have a default value" do
Super::ZSuperWithOptional::B.new.m(1, 2).should == 14
end

it "without explicit arguments passes optional arguments that have a non-default value" do
Super::ZSuperWithOptional::B.new.m(1, 2, 3).should == 3
end

it "without explicit arguments passes optional arguments that have a default value but were modified" do
Super::ZSuperWithOptional::C.new.m(1, 2).should == 100
end

it "without explicit arguments passes optional arguments that have a non-default value but were modified" do
Super::ZSuperWithOptional::C.new.m(1, 2, 3).should == 100
end

it "without explicit arguments passes rest arguments" do
Super::ZSuperWithRest::B.new.m(1, 2, 3).should == [1, 2, 3]
end

it "without explicit arguments passes rest arguments including any modifications" do
Super::ZSuperWithRest::B.new.m_modified(1, 2, 3).should == [1, 14, 3]
end

it "without explicit arguments passes arguments and rest arguments" do
Super::ZSuperWithRestAndOthers::B.new.m(1, 2, 3, 4, 5).should == [3, 4, 5]
end

it "without explicit arguments passes arguments and rest arguments including any modifications" do
Super::ZSuperWithRestAndOthers::B.new.m_modified(1, 2, 3, 4, 5).should == [3, 14, 5]
end

end
29 changes: 29 additions & 0 deletions spec/ruby/library/digest/bubblebabble_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require File.expand_path('../../../spec_helper', __FILE__)
require 'digest/bubblebabble'

describe "Digest.bubblebabble" do
it "returns a String" do
Digest.bubblebabble('').should be_an_instance_of(String)
end

it "returns a String in the The Bubble Babble Binary Data Encoding format" do
Digest.bubblebabble('').should == 'xexax'
Digest.bubblebabble('foo').should == 'xinik-zorox'
Digest.bubblebabble('bar').should == 'ximik-cosex'
Digest.bubblebabble('1234567890').should == 'xesef-disof-gytuf-katof-movif-baxux'
end

it "calls #to_str on an object and returns the bubble babble value of the result" do
obj = mock("to_str")
obj.should_receive(:to_str).and_return('foo')
Digest.bubblebabble(obj).should == 'xinik-zorox'
end

it "raises a TypeError when passed nil" do
lambda { Digest.bubblebabble(nil) }.should raise_error(TypeError)
end

it "raises a TypeError when passed a Fixnum" do
lambda { Digest.bubblebabble(9001) }.should raise_error(TypeError)
end
end
2 changes: 2 additions & 0 deletions spec/truffle/tags/core/argf/binmode_tags.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
fails:ARGF.binmode does not raise an error
fails:ARGF.binmode puts reading into binmode
fails:ARGF.binmode puts alls subsequent stream reading through ARGF into binmode
fails:ARGF.binmode returns self
fails:ARGF.binmode sets the file's encoding to ASCII-8BIT
3 changes: 0 additions & 3 deletions spec/truffle/tags/core/argf/bytes_tags.txt

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/core/argf/chars_tags.txt

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/core/argf/close_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
fails:ARGF.close closes the current open stream
fails:ARGF.close returns self
fails:ARGF.close raises an IOError if called on a closed stream
fails:ARGF.close can close STDIN
1 change: 0 additions & 1 deletion spec/truffle/tags/core/argf/closed_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/truffle/tags/core/argf/codepoints_tags.txt

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/core/argf/each_byte_tags.txt

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/core/argf/each_char_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/truffle/tags/core/argf/each_codepoint_tags.txt

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/core/argf/each_line_tags.txt

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/core/argf/each_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/truffle/tags/core/argf/eof_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
fails:ARGF.eof returns true when reaching the end of a file
fails:ARGF.eof raises IOError when called on a closed stream
fails:ARGF.eof? returns true when reaching the end of a file
fails:ARGF.eof? raises IOError when called on a closed stream
1 change: 0 additions & 1 deletion spec/truffle/tags/core/argf/file_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/argf/filename_tags.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
fails:ARGF.filename returns the current file name on each file
fails:ARGF.filename sets the $FILENAME global variable with the current file name on each file
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/argf/fileno_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/truffle/tags/core/argf/getc_tags.txt

This file was deleted.

5 changes: 0 additions & 5 deletions spec/truffle/tags/core/argf/gets_tags.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
fails:ARGF.gets reads one line of a file
fails:ARGF.gets reads all lines of a file
fails:ARGF.gets reads all lines of two files
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
fails:ARGF.gets returns nil when reaching end of files
fails:ARGF.gets reads the contents of the file with default encoding
3 changes: 0 additions & 3 deletions spec/truffle/tags/core/argf/lineno_tags.txt

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/core/argf/lines_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/argf/path_tags.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
fails:ARGF.path returns the current file name on each file
fails:ARGF.path sets the $FILENAME global variable with the current file name on each file
3 changes: 0 additions & 3 deletions spec/truffle/tags/core/argf/pos_tags.txt

This file was deleted.

12 changes: 0 additions & 12 deletions spec/truffle/tags/core/argf/read_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/truffle/tags/core/argf/readchar_tags.txt

This file was deleted.

4 changes: 0 additions & 4 deletions spec/truffle/tags/core/argf/readline_tags.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
fails:ARGF.readline reads one line of a file
fails:ARGF.readline reads all lines of a file
fails:ARGF.readline reads all lines of two files
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
fails:ARGF.readline raises an EOFError when reaching end of files
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/argf/readlines_tags.txt

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/core/argf/rewind_tags.txt

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/core/argf/seek_tags.txt

This file was deleted.

4 changes: 0 additions & 4 deletions spec/truffle/tags/core/argf/set_encoding_tags.txt

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/core/argf/skip_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/truffle/tags/core/argf/tell_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/truffle/tags/core/argf/to_a_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/truffle/tags/core/argf/to_i_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/argf/to_io_tags.txt

This file was deleted.

19 changes: 0 additions & 19 deletions spec/truffle/tags/core/kernel/putc_tags.txt

This file was deleted.

5 changes: 0 additions & 5 deletions spec/truffle/tags/core/module/class_eval_tags.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,2 @@
fails:Module#class_eval uses the optional filename and lineno parameters for error messages
fails:Module#class_eval converts a non-string filename to a string using to_str
fails:Module#class_eval raises a TypeError when the given filename can't be converted to string using to_str
fails:Module#class_eval converts non string eval-string to string using to_str
fails:Module#class_eval raises a TypeError when the given eval-string can't be converted to string using to_str
fails:Module#class_eval raises an ArgumentError when a block and normal arguments are given
fails:Module#class_eval adds methods respecting the lexical constant scope
3 changes: 0 additions & 3 deletions spec/truffle/tags/core/module/class_exec_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/module/initialize_tags.txt

This file was deleted.

5 changes: 0 additions & 5 deletions spec/truffle/tags/core/module/module_eval_tags.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,2 @@
fails:Module#module_eval uses the optional filename and lineno parameters for error messages
fails:Module#module_eval converts a non-string filename to a string using to_str
fails:Module#module_eval raises a TypeError when the given filename can't be converted to string using to_str
fails:Module#module_eval converts non string eval-string to string using to_str
fails:Module#module_eval raises a TypeError when the given eval-string can't be converted to string using to_str
fails:Module#module_eval raises an ArgumentError when a block and normal arguments are given
fails:Module#module_eval adds methods respecting the lexical constant scope
3 changes: 0 additions & 3 deletions spec/truffle/tags/core/module/module_exec_tags.txt

This file was deleted.

4 changes: 2 additions & 2 deletions spec/truffle/tags/language/super_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
fails:The super keyword passes along modified rest args when they weren't originally empty
fails:The super keyword passes along modified rest args when they were originally empty
fails:The super keyword raises a RuntimeError when called with implicit arguments from a method defined with define_method
fails:The super keyword calls method_missing when a superclass method is not found
fails:The super keyword without explicit arguments passes arguments and rest arguments
fails:The super keyword without explicit arguments passes arguments and rest arguments including any modifications
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/bigdecimal/abs_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:BigDecimal#abs returns the absolute value
fails:BigDecimal#abs properly handles special values
11 changes: 11 additions & 0 deletions spec/truffle/tags/library/bigdecimal/add_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
fails:BigDecimal#add returns a + [Fixnum value] with given precision
fails:BigDecimal#add returns a + [Bignum value] with given precision
fails:BigDecimal#add favors the precision specified in the second argument over the global limit
fails:BigDecimal#add uses the current rounding mode if rounding is needed
fails:BigDecimal#add uses the default ROUND_HALF_UP rounding if it wasn't explicitly changed
fails:BigDecimal#add returns NaN if NaN is involved
fails:BigDecimal#add returns Infinity or -Infinity if these are involved
fails:BigDecimal#add returns NaN if Infinity + (- Infinity)
fails:BigDecimal#add raises TypeError when adds nil
fails:BigDecimal#add raises TypeError when precision parameter is nil
fails:BigDecimal#add raises ArgumentError when precision parameter is negative
6 changes: 6 additions & 0 deletions spec/truffle/tags/library/bigdecimal/case_compare_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fails:BigDecimal#=== tests for equality
fails:BigDecimal#=== NaN is never equal to any number
fails:BigDecimal#=== returns true for infinity values with the same sign
fails:BigDecimal#=== returns false for infinity values with different signs
fails:BigDecimal#=== returns false when infinite value compared to finite one
fails:BigDecimal#=== returns false when compared objects that can not be coerced into BigDecimal
6 changes: 6 additions & 0 deletions spec/truffle/tags/library/bigdecimal/ceil_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fails:BigDecimal#ceil returns an Integer, if n is unspecified
fails:BigDecimal#ceil returns a BigDecimal, if n is specified
fails:BigDecimal#ceil returns the smallest integer greater or equal to self, if n is unspecified
fails:BigDecimal#ceil raise exception, if self is special value
fails:BigDecimal#ceil returns n digits right of the decimal point if given n > 0
fails:BigDecimal#ceil sets n digits left of the decimal point to 0, if given n < 0
1 change: 1 addition & 0 deletions spec/truffle/tags/library/bigdecimal/coerce_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:BigDecimal#coerce returns [other, self] both as BigDecimal
5 changes: 5 additions & 0 deletions spec/truffle/tags/library/bigdecimal/comparison_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
fails:BigDecimal#<=> returns 0 if a == b
fails:BigDecimal#<=> returns 1 if a > b
fails:BigDecimal#<=> returns -1 if a < b
fails:BigDecimal#<=> returns nil if NaN is involved
fails:BigDecimal#<=> returns nil if the argument is nil
15 changes: 15 additions & 0 deletions spec/truffle/tags/library/bigdecimal/div_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
fails:BigDecimal#div with precision set to 0 returns a / b
fails:BigDecimal#div with precision set to 0 returns 0 if divided by Infinity
fails:BigDecimal#div with precision set to 0 returns (+|-) Infinity if (+|-) Infinity divided by one
fails:BigDecimal#div with precision set to 0 returns NaN if Infinity / ((+|-) Infinity)
fails:BigDecimal#div with precision set to 0 returns (+|-) Infinity if divided by zero
fails:BigDecimal#div with precision set to 0 returns NaN if zero is divided by zero
fails:BigDecimal#div returns a / b with optional precision
fails:BigDecimal#div raises FloatDomainError if NaN is involved
fails:BigDecimal#div returns 0 if divided by Infinity and no precision given
fails:BigDecimal#div returns 0 if divided by Infinity with given precision
fails:BigDecimal#div raises ZeroDivisionError if divided by zero and no precision given
fails:BigDecimal#div returns NaN if zero is divided by zero
fails:BigDecimal#div raises FloatDomainError if (+|-) Infinity divided by 1 and no precision given
fails:BigDecimal#div returns (+|-)Infinity if (+|-)Infinity by 1 and precision given
fails:BigDecimal#div returns NaN if Infinity / ((+|-) Infinity)
6 changes: 6 additions & 0 deletions spec/truffle/tags/library/bigdecimal/divide_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fails:BigDecimal#/ returns a / b
fails:BigDecimal#/ returns 0 if divided by Infinity
fails:BigDecimal#/ returns (+|-) Infinity if (+|-) Infinity divided by one
fails:BigDecimal#/ returns NaN if Infinity / ((+|-) Infinity)
fails:BigDecimal#/ returns (+|-) Infinity if divided by zero
fails:BigDecimal#/ returns NaN if zero is divided by zero
16 changes: 16 additions & 0 deletions spec/truffle/tags/library/bigdecimal/divmod_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
fails:BigDecimal#mod_part_of_divmod returns self modulo other
fails:BigDecimal#mod_part_of_divmod returns a [Float value] when the argument is Float
fails:BigDecimal#mod_part_of_divmod returns NaN if NaN is involved
fails:BigDecimal#mod_part_of_divmod returns NaN if the dividend is Infinity
fails:BigDecimal#mod_part_of_divmod returns the dividend if the divisor is Infinity
fails:BigDecimal#mod_part_of_divmod raises TypeError if the argument cannot be coerced to BigDecimal
fails:BigDecimal#mod_part_of_divmod raises ZeroDivisionError if other is zero
fails:BigDecimal#divmod divides value, returns an array
fails:BigDecimal#divmod array contains quotient and modulus as BigDecimal
fails:BigDecimal#divmod Can be reversed with * and +
fails:BigDecimal#divmod returns an array of two NaNs if NaN is involved
fails:BigDecimal#divmod raises ZeroDivisionError if the divisor is zero
fails:BigDecimal#divmod returns an array of Infinity and NaN if the dividend is Infinity
fails:BigDecimal#divmod returns an array of zero and the dividend if the divisor is Infinity
fails:BigDecimal#divmod returns an array of two zero if the diviend is zero
fails:BigDecimal#divmod raises TypeError if the argument cannot be coerced to BigDecimal
1 change: 1 addition & 0 deletions spec/truffle/tags/library/bigdecimal/double_fig_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:BigDecimal.double_fig returns the number of digits a Float number is allowed to have
6 changes: 6 additions & 0 deletions spec/truffle/tags/library/bigdecimal/eql_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fails:BigDecimal#eql? tests for equality
fails:BigDecimal#eql? NaN is never equal to any number
fails:BigDecimal#eql? returns true for infinity values with the same sign
fails:BigDecimal#eql? returns false for infinity values with different signs
fails:BigDecimal#eql? returns false when infinite value compared to finite one
fails:BigDecimal#eql? returns false when compared objects that can not be coerced into BigDecimal
6 changes: 6 additions & 0 deletions spec/truffle/tags/library/bigdecimal/equal_value_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fails:BigDecimal#== tests for equality
fails:BigDecimal#== NaN is never equal to any number
fails:BigDecimal#== returns true for infinity values with the same sign
fails:BigDecimal#== returns false for infinity values with different signs
fails:BigDecimal#== returns false when infinite value compared to finite one
fails:BigDecimal#== returns false when compared objects that can not be coerced into BigDecimal
11 changes: 11 additions & 0 deletions spec/truffle/tags/library/bigdecimal/exponent_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
fails:BigDecimal#** powers of self
fails:BigDecimal#** powers of 1 equal 1
fails:BigDecimal#** 0 to power of 0 is 1
fails:BigDecimal#** 0 to powers < 0 is Infinity
fails:BigDecimal#** other powers of 0 are 0
fails:BigDecimal#** returns NaN if self is NaN
fails:BigDecimal#** returns 0.0 if self is infinite and argument is negative
fails:BigDecimal#** returns infinite if self is infinite and argument is positive
fails:BigDecimal#exponent returns an Integer
fails:BigDecimal#exponent is n if number can be represented as 0.xxx*10**n
fails:BigDecimal#exponent returns 0 if self is 0
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/bigdecimal/finite_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:BigDecimal#finite? is false if Infinity or NaN
fails:BigDecimal#finite? returns true for finite values
5 changes: 5 additions & 0 deletions spec/truffle/tags/library/bigdecimal/fix_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
fails:BigDecimal#fix returns a BigDecimal
fails:BigDecimal#fix returns the integer part of the absolute value
fails:BigDecimal#fix correctly handles special values
fails:BigDecimal#fix returns 0 if the absolute value is < 1
fails:BigDecimal#fix does not allow any arguments
4 changes: 4 additions & 0 deletions spec/truffle/tags/library/bigdecimal/floor_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fails:BigDecimal#floor returns the greatest integer smaller or equal to self
fails:BigDecimal#floor raise exception, if self is special value
fails:BigDecimal#floor returns n digits right of the decimal point if given n > 0
fails:BigDecimal#floor sets n digits left of the decimal point to 0, if given n < 0
5 changes: 5 additions & 0 deletions spec/truffle/tags/library/bigdecimal/frac_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
fails:BigDecimal#frac returns a BigDecimal
fails:BigDecimal#frac returns the fractional part of the absolute value
fails:BigDecimal#frac returns 0 if the value is 0
fails:BigDecimal#frac returns 0 if the value is an integer
fails:BigDecimal#frac correctly handles special values
4 changes: 4 additions & 0 deletions spec/truffle/tags/library/bigdecimal/gt_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fails:BigDecimal#> returns true if a > b
fails:BigDecimal#> properly handles infinity values
fails:BigDecimal#> properly handles NaN values
fails:BigDecimal#> raises an ArgumentError if the argument can't be coerced into a BigDecimal
4 changes: 4 additions & 0 deletions spec/truffle/tags/library/bigdecimal/gte_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fails:BigDecimal#>= returns true if a >= b
fails:BigDecimal#>= properly handles infinity values
fails:BigDecimal#>= properly handles NaN values
fails:BigDecimal#>= returns nil if the argument is nil
4 changes: 4 additions & 0 deletions spec/truffle/tags/library/bigdecimal/infinite_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fails:BigDecimal#infinite? returns 1 if self is Infinity
fails:BigDecimal#infinite? returns -1 if self is -Infinity
fails:BigDecimal#infinite? returns not true otherwise
fails:BigDecimal#infinite? returns not true if self is NaN
7 changes: 7 additions & 0 deletions spec/truffle/tags/library/bigdecimal/inspect_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
fails:BigDecimal#inspect returns String
fails:BigDecimal#inspect returns String starting with #
fails:BigDecimal#inspect encloses information in angle brackets
fails:BigDecimal#inspect is comma separated list of three items
fails:BigDecimal#inspect value after first comma is value as string
fails:BigDecimal#inspect last part is number of significant digits
fails:BigDecimal#inspect looks like this
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/bigdecimal/limit_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:BigDecimal.limit returns the value before set if the passed argument is nil or is not specified
fails:BigDecimal.limit use the global limit if no precision is specified
4 changes: 4 additions & 0 deletions spec/truffle/tags/library/bigdecimal/lt_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fails:BigDecimal#< returns true if a < b
fails:BigDecimal#< properly handles infinity values
fails:BigDecimal#< properly handles NaN values
fails:BigDecimal#< raises an ArgumentError if the argument can't be coerced into a BigDecimal
4 changes: 4 additions & 0 deletions spec/truffle/tags/library/bigdecimal/lte_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fails:BigDecimal#<= returns true if a <= b
fails:BigDecimal#<= properly handles infinity values
fails:BigDecimal#<= properly handles NaN values
fails:BigDecimal#<= raises an ArgumentError if the argument can't be coerced into a BigDecimal
3 changes: 3 additions & 0 deletions spec/truffle/tags/library/bigdecimal/minus_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fails:BigDecimal#- returns NaN if NaN is involved
fails:BigDecimal#- returns NaN both operands are infinite with the same sign
fails:BigDecimal#- returns Infinity or -Infinity if these are involved
3 changes: 3 additions & 0 deletions spec/truffle/tags/library/bigdecimal/mode_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fails:BigDecimal.mode returns the appropriate value and continue the computation if the flag is false
fails:BigDecimal.mode returns Infinity when too big
fails:BigDecimal.mode raise an exception if the flag is true
14 changes: 14 additions & 0 deletions spec/truffle/tags/library/bigdecimal/modulo_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
fails:BigDecimal#% returns self modulo other
fails:BigDecimal#% returns a [Float value] when the argument is Float
fails:BigDecimal#% returns NaN if NaN is involved
fails:BigDecimal#% returns NaN if the dividend is Infinity
fails:BigDecimal#% returns the dividend if the divisor is Infinity
fails:BigDecimal#% raises TypeError if the argument cannot be coerced to BigDecimal
fails:BigDecimal#% raises ZeroDivisionError if other is zero
fails:BigDecimal#modulo returns self modulo other
fails:BigDecimal#modulo returns a [Float value] when the argument is Float
fails:BigDecimal#modulo returns NaN if NaN is involved
fails:BigDecimal#modulo returns NaN if the dividend is Infinity
fails:BigDecimal#modulo returns the dividend if the divisor is Infinity
fails:BigDecimal#modulo raises TypeError if the argument cannot be coerced to BigDecimal
fails:BigDecimal#modulo raises ZeroDivisionError if other is zero
6 changes: 6 additions & 0 deletions spec/truffle/tags/library/bigdecimal/mult_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fails:BigDecimal#mult returns zero of appropriate sign if self or argument is zero
fails:BigDecimal#mult returns NaN if NaN is involved
fails:BigDecimal#mult returns zero if self or argument is zero
fails:BigDecimal#mult returns infinite value if self or argument is infinite
fails:BigDecimal#mult returns NaN if the result is undefined
fails:BigDecimal#mult multiply self with other with (optional) precision
6 changes: 6 additions & 0 deletions spec/truffle/tags/library/bigdecimal/multiply_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fails:BigDecimal#* returns zero of appropriate sign if self or argument is zero
fails:BigDecimal#* returns NaN if NaN is involved
fails:BigDecimal#* returns zero if self or argument is zero
fails:BigDecimal#* returns infinite value if self or argument is infinite
fails:BigDecimal#* returns NaN if the result is undefined
fails:BigDecimal#* multiply self with other
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/bigdecimal/nan_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:BigDecimal#nan? returns true if self is not a number
fails:BigDecimal#nan? returns false if self is not a NaN
12 changes: 12 additions & 0 deletions spec/truffle/tags/library/bigdecimal/new_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
fails:BigDecimal.new creates a new object of class BigDecimal
fails:BigDecimal.new doesn't segfault when using a very large string to build the number
fails:BigDecimal.new Number of significant digits >= given precision
fails:BigDecimal.new determines precision from initial value
fails:BigDecimal.new ignores leading whitespace
fails:BigDecimal.new ignores trailing garbage
fails:BigDecimal.new treats invalid strings as 0.0
fails:BigDecimal.new allows omitting the integer part
fails:BigDecimal.new allows for underscores in all parts
fails:BigDecimal.new accepts NaN and [+-]Infinity
fails:BigDecimal.new allows for [eEdD] as exponent separator
fails:BigDecimal.new allows for varying signs
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/bigdecimal/nonzero_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:BigDecimal#nonzero? returns self if self doesn't equal zero
fails:BigDecimal#nonzero? returns nil otherwise
3 changes: 3 additions & 0 deletions spec/truffle/tags/library/bigdecimal/plus_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fails:BigDecimal#+ returns NaN if NaN is involved
fails:BigDecimal#+ returns Infinity or -Infinity if these are involved
fails:BigDecimal#+ returns NaN if Infinity + (- Infinity)
8 changes: 8 additions & 0 deletions spec/truffle/tags/library/bigdecimal/power_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
fails:BigDecimal#power powers of self
fails:BigDecimal#power powers of 1 equal 1
fails:BigDecimal#power 0 to power of 0 is 1
fails:BigDecimal#power 0 to powers < 0 is Infinity
fails:BigDecimal#power other powers of 0 are 0
fails:BigDecimal#power returns NaN if self is NaN
fails:BigDecimal#power returns 0.0 if self is infinite and argument is negative
fails:BigDecimal#power returns infinite if self is infinite and argument is positive
4 changes: 4 additions & 0 deletions spec/truffle/tags/library/bigdecimal/precs_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fails:BigDecimal#precs returns array of two values
fails:BigDecimal#precs returns Integers as array values
fails:BigDecimal#precs returns the current value of significant digits as the first value
fails:BigDecimal#precs returns the maximum number of significant digits as the second value
7 changes: 7 additions & 0 deletions spec/truffle/tags/library/bigdecimal/quo_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
fails:BigDecimal#quo returns a / b
fails:BigDecimal#quo returns 0 if divided by Infinity
fails:BigDecimal#quo returns (+|-) Infinity if (+|-) Infinity divided by one
fails:BigDecimal#quo returns NaN if Infinity / ((+|-) Infinity)
fails:BigDecimal#quo returns (+|-) Infinity if divided by zero
fails:BigDecimal#quo returns NaN if zero is divided by zero
fails:BigDecimal#quo returns NaN if NaN is involved
8 changes: 8 additions & 0 deletions spec/truffle/tags/library/bigdecimal/remainder_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
fails:BigDecimal#remainder it equals modulo, if both values are of same sign
fails:BigDecimal#remainder means self-arg*(self/arg).truncate
fails:BigDecimal#remainder returns NaN used with zero
fails:BigDecimal#remainder returns zero if used on zero
fails:BigDecimal#remainder returns NaN if NaN is involved
fails:BigDecimal#remainder returns NaN if Infinity is involved
fails:BigDecimal#remainder coerces arguments to BigDecimal if possible
fails:BigDecimal#remainder raises TypeError if the argument cannot be coerced to BigDecimal
8 changes: 8 additions & 0 deletions spec/truffle/tags/library/bigdecimal/round_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
fails:BigDecimal#round uses default rounding method unless given
fails:BigDecimal#round BigDecimal::ROUND_UP rounds values away from zero
fails:BigDecimal#round BigDecimal::ROUND_DOWN rounds values towards zero
fails:BigDecimal#round BigDecimal::ROUND_HALF_UP rounds values >= 5 up, otherwise down
fails:BigDecimal#round BigDecimal::ROUND_HALF_DOWN rounds values > 5 up, otherwise down
fails:BigDecimal#round BigDecimal::ROUND_CEILING rounds values towards +infinity
fails:BigDecimal#round BigDecimal::ROUND_FLOOR rounds values towards -infinity
fails:BigDecimal#round BigDecimal::ROUND_HALF_EVEN rounds values > 5 up, < 5 down and == 5 towards even neighbor
6 changes: 6 additions & 0 deletions spec/truffle/tags/library/bigdecimal/sign_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fails:BigDecimal#sign BigDecimal defines several constants for signs
fails:BigDecimal#sign returns positive value if BigDecimal greater than 0
fails:BigDecimal#sign returns negative value if BigDecimal less than 0
fails:BigDecimal#sign returns positive zero if BigDecimal equals positve zero
fails:BigDecimal#sign returns negative zero if BigDecimal equals negative zero
fails:BigDecimal#sign returns BigDecimal::SIGN_NaN if BigDecimal is NaN
7 changes: 7 additions & 0 deletions spec/truffle/tags/library/bigdecimal/split_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
fails:BigDecimal#split splits BigDecimal in an array with four values
fails:BigDecimal#split First value: 1 for numbers > 0
fails:BigDecimal#split First value: -1 for numbers < 0
fails:BigDecimal#split First value: 0 if BigDecimal is NaN
fails:BigDecimal#split Second value: a string with the significant digits
fails:BigDecimal#split Third value: the base (currently always ten)
fails:BigDecimal#split Fourth value: The exponent
16 changes: 16 additions & 0 deletions spec/truffle/tags/library/bigdecimal/sqrt_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
fails:BigDecimal#sqrt returns square root of 2 with desired precision
fails:BigDecimal#sqrt returns square root of 3 with desired precision
fails:BigDecimal#sqrt returns square root of 121 with desired precision
fails:BigDecimal#sqrt returns square root of 0.9E-99999 with desired precision
fails:BigDecimal#sqrt raises ArgumentError when no argument is given
fails:BigDecimal#sqrt raises ArgumentError if a negative number is given
fails:BigDecimal#sqrt raises ArgumentError if 2 arguments are given
fails:BigDecimal#sqrt raises TypeError if nil is given
fails:BigDecimal#sqrt raises TypeError if a string is given
fails:BigDecimal#sqrt raises TypeError if a plain Object is given
fails:BigDecimal#sqrt returns 1 if precision is 0 or 1
fails:BigDecimal#sqrt raises FloatDomainError on negative values
fails:BigDecimal#sqrt returns positive infitinity for infinity
fails:BigDecimal#sqrt raises FloatDomainError for negative infinity
fails:BigDecimal#sqrt raises FloatDomainError for NaN
fails:BigDecimal#sqrt returns 0 for 0, +0.0 and -0.0
3 changes: 3 additions & 0 deletions spec/truffle/tags/library/bigdecimal/sub_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fails:BigDecimal#sub returns NaN if NaN is involved
fails:BigDecimal#sub returns NaN if both values are infinite with the same signs
fails:BigDecimal#sub returns Infinity or -Infinity if these are involved
4 changes: 4 additions & 0 deletions spec/truffle/tags/library/bigdecimal/to_f_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fails:BigDecimal#to_f returns number of type float
fails:BigDecimal#to_f Floating point rounding occurs
fails:BigDecimal#to_f properly handles special values
fails:BigDecimal#to_f remembers negative zero when converted to float
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/bigdecimal/to_i_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:BigDecimal#to_i raises FloatDomainError if BigDecimal is infinity or NaN
fails:BigDecimal#to_i returns Integer or Bignum otherwise
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/bigdecimal/to_int_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:BigDecimal#to_int raises FloatDomainError if BigDecimal is infinity or NaN
fails:BigDecimal#to_int returns Integer or Bignum otherwise
8 changes: 8 additions & 0 deletions spec/truffle/tags/library/bigdecimal/to_s_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
fails:BigDecimal#to_s the default format looks like 0.xxxxEnn
fails:BigDecimal#to_s takes an optional argument
fails:BigDecimal#to_s starts with + if + is supplied and value is positive
fails:BigDecimal#to_s inserts a space every n chars, if integer n is supplied
fails:BigDecimal#to_s can return a leading space for values > 0
fails:BigDecimal#to_s removes trailing spaces in floating point notation
fails:BigDecimal#to_s can use engineering notation
fails:BigDecimal#to_s can use conventional floating point notation
7 changes: 7 additions & 0 deletions spec/truffle/tags/library/bigdecimal/truncate_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
fails:BigDecimal#truncate returns value of type Integer.
fails:BigDecimal#truncate returns the integer part as a BigDecimal if no precision given
fails:BigDecimal#truncate returns value of given precision otherwise
fails:BigDecimal#truncate sets n digits left of the decimal point to 0, if given n < 0
fails:BigDecimal#truncate returns NaN if self is NaN
fails:BigDecimal#truncate returns Infinity if self is infinite
fails:BigDecimal#truncate returns the same value if self is special value
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/bigdecimal/uminus_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:BigDecimal#-@ negates self
fails:BigDecimal#-@ properly handles special values
1 change: 1 addition & 0 deletions spec/truffle/tags/library/bigdecimal/uplus_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:BigDecimal#+@ returns the same value with same sign (twos complement)
1 change: 1 addition & 0 deletions spec/truffle/tags/library/bigdecimal/ver_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:BigDecimal.ver returns the Version number
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/bigdecimal/zero_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:BigDecimal#zero? returns true if self does equal zero
fails:BigDecimal#zero? returns false otherwise
1 change: 1 addition & 0 deletions spec/truffle/tags/library/digest/bubblebabble_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Digest.bubblebabble returns a String in the The Bubble Babble Binary Data Encoding format
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/securerandom/base64_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:SecureRandom.base64 generates a random base64 string out of specified number of random bytes
fails:SecureRandom.base64 tries to convert the passed argument to an Integer using #to_int
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/securerandom/hex_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:SecureRandom.hex generates a random hex string of length twice the specified argement
fails:SecureRandom.hex tries to convert the passed argument to an Integer using #to_int
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/securerandom/random_bytes_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:SecureRandom.random_bytes generates a random binary string of specified length
fails:SecureRandom.random_bytes tries to convert the passed argument to an Integer using #to_int
2 changes: 0 additions & 2 deletions spec/truffle/tags/library/set/divide_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/truffle/tags/library/set/sortedset/divide_tags.txt

This file was deleted.

1 change: 1 addition & 0 deletions spec/truffle/tags/library/thread/sizedqueue/deq_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Thread::SizedQueue#deq raises a ThreadError if Queue is empty
1 change: 1 addition & 0 deletions spec/truffle/tags/library/thread/sizedqueue/pop_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Thread::SizedQueue#pop raises a ThreadError if Queue is empty
1 change: 1 addition & 0 deletions spec/truffle/tags/library/thread/sizedqueue/shift_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Thread::SizedQueue#shift raises a ThreadError if Queue is empty
5 changes: 5 additions & 0 deletions spec/truffle/tags/library/zlib/adler32_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
fails:Zlib.adler32 calculates Adler checksum for string
fails:Zlib.adler32 calculates Adler checksum for string and initial Adler value
fails:Zlib.adler32 calculates the Adler checksum for string and initial Adler value for Bignums
fails:Zlib.adler32 assumes that the initial value is given to adler, if adler is omitted
fails:Zlib.adler32 it returns the CRC initial value, if string is omitted
1 change: 1 addition & 0 deletions spec/truffle/tags/library/zlib/crc_table_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Zlib.crc_table returns the same value as zlib's get_crc_table()
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/zlib/deflate/deflate_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:Zlib::Deflate#deflate deflates some data
fails:Zlib::Deflate#deflate deflates lots of data
1 change: 1 addition & 0 deletions spec/truffle/tags/library/zlib/deflate/params_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Zlib::Deflate#params changes the deflate parameters
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Zlib::Deflate#set_dictionary sets the dictionary
1 change: 1 addition & 0 deletions spec/truffle/tags/library/zlib/gzipfile/close_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Zlib::GzipFile#close finishes the stream and closes the io
1 change: 1 addition & 0 deletions spec/truffle/tags/library/zlib/gzipfile/closed_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Zlib::GzipFile#closed? returns the closed status
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/zlib/gzipfile/comment_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:Zlib::GzipFile#comment returns the name
fails:Zlib::GzipFile#comment raises an error on a closed stream
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/zlib/gzipfile/orig_name_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:Zlib::GzipFile#orig_name returns the name
fails:Zlib::GzipFile#orig_name raises an error on a closed stream
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/zlib/gzipreader/each_byte_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:GzipReader#each_byte calls the given block for each byte in the stream, passing the byte as an argument
fails:GzipReader#each_byte increments position before calling the block
5 changes: 5 additions & 0 deletions spec/truffle/tags/library/zlib/gzipreader/eof_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
fails:GzipReader#eof? returns true when at EOF
fails:GzipReader#eof? returns true when at EOF with the exact length of uncompressed data
fails:GzipReader#eof? returns true when at EOF with a length greater than the size of uncompressed data
fails:GzipReader#eof? returns false when at EOF when there's data left in the buffer to read
fails:GzipReader#eof? does not affect the reading data
3 changes: 3 additions & 0 deletions spec/truffle/tags/library/zlib/gzipreader/getc_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fails:GzipReader#getc returns the next character from the stream
fails:GzipReader#getc increments position
fails:GzipReader#getc returns nil at the end of the stream
1 change: 1 addition & 0 deletions spec/truffle/tags/library/zlib/gzipreader/pos_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:GzipReader#pos returns the position
8 changes: 8 additions & 0 deletions spec/truffle/tags/library/zlib/gzipreader/read_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
fails:GzipReader#read with no arguments reads the entire content of a gzip file
fails:GzipReader#read with nil length argument reads the entire content of a gzip file
fails:GzipReader#read reads the contents up to a certain size
fails:GzipReader#read does not accept a negative length to read
fails:GzipReader#read returns an empty string if a 0 length is given
fails:GzipReader#read respects :external_encoding option
fails:GzipReader#read at the end of data returns empty string if length prameter is not specified or 0
fails:GzipReader#read at the end of data returns nil if length prameter is positive
3 changes: 3 additions & 0 deletions spec/truffle/tags/library/zlib/gzipreader/rewind_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fails:GzipReader#rewind resets the position of the stream pointer
fails:GzipReader#rewind resets the position of the stream pointer to data previously read
fails:GzipReader#rewind invokes seek method on the associated IO object
1 change: 1 addition & 0 deletions spec/truffle/tags/library/zlib/gzipwriter/append_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Zlib::GzipWriter#<< returns self
3 changes: 3 additions & 0 deletions spec/truffle/tags/library/zlib/gzipwriter/mtime_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fails:Zlib::GzipWriter#mtime= sets mtime using Integer
fails:Zlib::GzipWriter#mtime= sets mtime using Time
fails:Zlib::GzipWriter#mtime= raises if the header was written
3 changes: 3 additions & 0 deletions spec/truffle/tags/library/zlib/gzipwriter/write_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fails:GzipWriter#write writes some compressed data
fails:GzipWriter#write returns the number of bytes in the input
fails:GzipWriter#write handles inputs of 2^23 bytes
7 changes: 7 additions & 0 deletions spec/truffle/tags/library/zlib/inflate/append_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
fails:Zlib::Inflate#<< appends data to the input stream
fails:Zlib::Inflate#<< treats nil argument as the end of compressed data
fails:Zlib::Inflate#<< just passes through the data after nil argument
fails:Zlib::Inflate#<< properly handles data in chunks
fails:Zlib::Inflate#<< properly handles incomplete data
fails:Zlib::Inflate#<< properly handles excessive data, byte-by-byte
fails:Zlib::Inflate#<< properly handles excessive data, in one go
7 changes: 7 additions & 0 deletions spec/truffle/tags/library/zlib/inflate/inflate_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
fails:Zlib::Inflate#inflate inflates some data
fails:Zlib::Inflate#inflate inflates lots of data
fails:Zlib::Inflate#inflate works in pass-through mode, once finished
fails:Zlib::Inflate::inflate properly handles data in chunks
fails:Zlib::Inflate::inflate properly handles incomplete data
fails:Zlib::Inflate::inflate properly handles excessive data, byte-by-byte
fails:Zlib::Inflate::inflate properly handles excessive data, in one go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Zlib::Inflate#set_dictionary sets the inflate dictionary
1 change: 1 addition & 0 deletions spec/truffle/tags/library/zlib/zstream/adler_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Zlib::ZStream#adler generates hash
1 change: 1 addition & 0 deletions spec/truffle/tags/library/zlib/zstream/avail_in_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Zlib::ZStream#avail_in returns bytes in the input buffer
1 change: 1 addition & 0 deletions spec/truffle/tags/library/zlib/zstream/avail_out_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Zlib::ZStream#avail_out returns bytes in the output buffer
1 change: 1 addition & 0 deletions spec/truffle/tags/library/zlib/zstream/data_type_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Zlib::ZStream#data_type returns the type of the data in the stream
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Zlib::ZStream#flush_next_out flushes the stream and flushes the output buffer
12 changes: 8 additions & 4 deletions spec/truffle/truffle.mspec
Original file line number Diff line number Diff line change
@@ -95,6 +95,7 @@ class MSpecScript
"spec/ruby/library/date",
"spec/ruby/library/datetime",
"spec/ruby/library/delegate",
"spec/ruby/library/digest/md5",
"spec/ruby/library/cgi",
"spec/ruby/library/erb",
"spec/ruby/library/getoptlong",
@@ -108,6 +109,7 @@ class MSpecScript
"spec/ruby/library/prime",
"spec/ruby/library/resolv",
"spec/ruby/library/scanf",
"spec/ruby/library/securerandom",
"spec/ruby/library/set",
"spec/ruby/library/shellwords",
"spec/ruby/library/singleton",
@@ -118,12 +120,16 @@ class MSpecScript
"spec/ruby/library/time",
"spec/ruby/library/tmpdir",
"spec/ruby/library/uri",
"spec/ruby/library/bigdecimal",
"spec/ruby/library/zlib",

# Not yet explored
"^spec/ruby/library/bigdecimal",
"^spec/ruby/library/continuation",
"^spec/ruby/library/csv",
"^spec/ruby/library/digest",
"^spec/ruby/library/digest/sha1",
"^spec/ruby/library/digest/sha256",
"^spec/ruby/library/digest/sha384",
"^spec/ruby/library/digest/sha512",
"^spec/ruby/library/drb",
"^spec/ruby/library/etc",
"^spec/ruby/library/expect",
@@ -133,12 +139,10 @@ class MSpecScript
"^spec/ruby/library/openssl",
"^spec/ruby/library/readline",
"^spec/ruby/library/rexml",
"^spec/ruby/library/securerandom",
"^spec/ruby/library/syslog",
"^spec/ruby/library/timeout",
"^spec/ruby/library/weakref",
"^spec/ruby/library/win32ole",
"^spec/ruby/library/zlib",
"^spec/ruby/library/yaml",
"^spec/ruby/library/socket",

8 changes: 8 additions & 0 deletions test/mri/excludes_truffle/TC_IPAddr.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
exclude :test_ipv4_compat, "needs investigation"
exclude :test_ipv4_mapped, "needs investigation"
exclude :test_s_new, "needs investigation"
exclude :test_ip6_arpa, "needs investigation"
exclude :test_ip6_int, "needs investigation"
exclude :test_reverse, "needs investigation"
exclude :test_s_new_ntoh, "needs investigation"
exclude :test_to_s, "needs investigation"
9 changes: 9 additions & 0 deletions test/mri/excludes_truffle/TC_Operator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
exclude :test_hash, "needs investigation"
exclude :test_or, "needs investigation"
exclude :test_and, "needs investigation"
exclude :test_carrot, "needs investigation"
exclude :test_equal, "needs investigation"
exclude :test_include?, "needs investigation"
exclude :test_mask, "needs investigation"
exclude :test_shift_left, "needs investigation"
exclude :test_shift_right, "needs investigation"
2 changes: 2 additions & 0 deletions test/mri/excludes_truffle/TestBenchmark.rb
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
exclude :test_tms_outputs_nicely, "needs investigation"
exclude :test_benchmark_makes_extra_calcultations_with_an_Array_at_the_end_of_the_benchmark_and_show_the_result, "needs investigation"
exclude :test_bm_correctly_output_when_no_label_is_given, "needs investigation"
2 changes: 2 additions & 0 deletions test/mri/excludes_truffle/TestJSONAddition.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
exclude :test_bigdecimal, "needs investigation"
exclude :test_extended_json_fail2, "needs investigation"
17 changes: 17 additions & 0 deletions test/mri/excludes_truffle/TestRange.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
exclude :test_beg_len, "needs investigation"
exclude :test_bsearch_for_bignum, "needs investigation"
exclude :test_bsearch_for_fixnum, "needs investigation"
exclude :test_bsearch_for_float, "needs investigation"
exclude :test_bsearch_for_other_numerics, "needs investigation"
exclude :test_bsearch_with_mathn, "needs investigation"
exclude :test_comparison_when_recursive, "needs investigation"
exclude :test_cyclic_range_inspect, "needs investigation"
exclude :test_duckrange, "needs investigation"
exclude :test_each, "needs investigation"
exclude :test_each_no_blockarg, "needs investigation"
exclude :test_initialize_twice, "needs investigation"
exclude :test_max, "needs investigation"
exclude :test_min, "needs investigation"
exclude :test_range_bsearch_for_floats, "needs investigation"
exclude :test_range_numeric_string, "needs investigation"
exclude :test_size, "needs investigation"
8 changes: 4 additions & 4 deletions test/mri_truffle.index
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@

ruby/test_alias.rb

# ruby/test_argf.rb
# ruby/test_argf.rb # spawn needed for tests
# ruby/test_array.rb # StackOverflowError null java.lang.ClassLoader.getClassLoadingLock(ClassLoader.java:461) (RubyTruffleError)
ruby/test_assignment.rb
ruby/test_autoload.rb
@@ -71,7 +71,7 @@ ruby/test_proc.rb

# ruby/test_process.rb # cannot load such file -- io/wait
ruby/test_rand.rb
# ruby/test_range.rb # cannot load such file -- bigdecimal
ruby/test_range.rb
ruby/test_rational.rb
ruby/test_rational2.rb
ruby/test_readpartial.rb
@@ -107,7 +107,7 @@ test_pp.rb
test_cmath.rb
test_delegate.rb
test_find.rb
# test_ipaddr.rb # cannot load such file -- ipaddr
test_ipaddr.rb

test_mathn.rb

@@ -191,7 +191,7 @@ fileutils/test_verbose.rb
io/console/test_io_console.rb

json/test_json.rb
# json/test_json_addition.rb # cannot load such file -- bigdecimal
json/test_json_addition.rb
json/test_json_encoding.rb
json/test_json_fixtures.rb
json/test_json_generate.rb
11 changes: 3 additions & 8 deletions tool/jt.rb
Original file line number Diff line number Diff line change
@@ -167,12 +167,11 @@ def help
puts 'jt bench debug benchmark run a single benchmark with options for compiler debugging'
puts 'jt bench reference [benchmarks] run a set of benchmarks and record a reference point'
puts 'jt bench compare [benchmarks] run a set of benchmarks and compare against a reference point'
puts ' benchmarks can be any benchmarks of group of benchmarks supported'
puts ' benchmarks can be any benchmarks or group of benchmarks supported'
puts ' by bench9000, eg all, classic, chunky, 3, 5, 10, 15 - default is 5'
puts 'jt findbugs run findbugs'
puts 'jt findbugs report run findbugs and generate an HTML report'
puts 'jt install ..../graal/mx/suite.py install a JRuby distribution into an mx suite'
puts 'jt poms rebuild Maven POM XML files from Ruby files'
puts
puts 'you can also put build or rebuild in front of any command'
puts
@@ -249,14 +248,14 @@ def e(*args)
end

def print(*args)
e 'puts', *args
e 'puts begin', *args, 'end'
end

def test_mri(*args)
env_vars = {
"EXCLUDES" => "test/mri/excludes_truffle"
}
jruby_args = %w[-J-Xmx4G -X+T -Xtruffle.exceptions.print_java]
jruby_args = %w[-J-Xmx2G -X+T -Xtruffle.exceptions.print_java]

if args.empty?
args = File.readlines("#{JRUBY_DIR}/test/mri_truffle.index").grep(/^[^#]\w+/).map(&:chomp)
@@ -395,10 +394,6 @@ def install(arg)
raise ArgumentError, kind
end
end

def poms
sh 'rake', 'maven:dump_poms'
end
end

class JT
4 changes: 4 additions & 0 deletions tool/truffle-findbugs-exclude.xml
Original file line number Diff line number Diff line change
@@ -134,6 +134,10 @@
<Class name="org.jruby.truffle.pack.runtime.PackResult" />
<Bug pattern="EI_EXPOSE_REP" />
</Match>
<Match>
<Class name="org.jruby.truffle.nodes.control.SequenceNode" />
<Bug pattern="EI_EXPOSE_REP" />
</Match>

<!-- Hacks that should go away at some point -->

This file was deleted.

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

import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.KernelNodes.RequireNode;
import org.jruby.truffle.nodes.core.KernelNodesFactory;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.runtime.RubyConstant;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyModule;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.truffle.runtime.core.RubySymbol;

import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;

@NodeChildren({
@NodeChild("module"), @NodeChild("name"),
@NodeChild(value = "lookupConstantNode", type = LookupConstantNode.class, executeWith = { "module", "name" })
})
public abstract class GetConstantNode extends RubyNode {

public GetConstantNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public abstract RubyNode getModule();
public abstract LookupConstantNode getLookupConstantNode();

public abstract Object executeGetConstant(VirtualFrame frame, Object module, String name);

@Specialization(guards = { "constant != null", "!constant.isAutoload()" })
protected Object getConstant(RubyModule module, String name, RubyConstant constant) {
return constant.getValue();
}

@Specialization(guards = { "constant != null", "constant.isAutoload()" })
protected Object autoloadConstant(VirtualFrame frame, RubyModule module, String name, RubyConstant constant,
@Cached("createRequireNode()") RequireNode requireNode) {

requireNode.require((RubyString) constant.getValue());

// retry
return this.executeGetConstant(frame, module, name);
}

@Specialization(guards = "constant == null")
protected Object missingConstant(VirtualFrame frame, RubyModule module, String name, Object constant,
@Cached("createConstMissingNode()") CallDispatchHeadNode constMissingNode,
@Cached("getContext().getSymbol(name)") RubySymbol symbolName) {
return constMissingNode.call(frame, module, "const_missing", null, symbolName);
}

protected RequireNode createRequireNode() {
return KernelNodesFactory.RequireNodeFactory.create(getContext(), getSourceSection(), new RubyNode[] {});
}

protected CallDispatchHeadNode createConstMissingNode() {
return DispatchHeadNodeFactory.createMethodCall(getContext());
}

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

import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.dispatch.DispatchNode;
import org.jruby.truffle.runtime.LexicalScope;
import org.jruby.truffle.runtime.ModuleOperations;
import org.jruby.truffle.runtime.RubyConstant;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyModule;

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.NodeChild;
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;

@NodeChildren({ @NodeChild("module"), @NodeChild("name") })
public abstract class LookupConstantNode extends RubyNode {

public static int getCacheLimit() {
return DispatchNode.DISPATCH_POLYMORPHIC_MAX;
}

private final LexicalScope lexicalScope;

public LookupConstantNode(RubyContext context, SourceSection sourceSection, LexicalScope lexicalScope) {
super(context, sourceSection);
this.lexicalScope = lexicalScope;
}

public LexicalScope getLexicalScope() {
return lexicalScope;
}

public abstract RubyConstant executeLookupConstant(VirtualFrame frame, Object module, String name);

@Specialization(guards = {
"module == cachedModule",
"name.equals(cachedName)"
}, assumptions = "cachedModule.getUnmodifiedAssumption()", limit = "getCacheLimit()")
protected RubyConstant lookupConstant(VirtualFrame frame, RubyModule module, String name,
@Cached("module") RubyModule cachedModule,
@Cached("name") String cachedName,
@Cached("doLookup(cachedModule, cachedName)") RubyConstant constant,
@Cached("isVisible(cachedModule, constant)") boolean isVisible) {
if (!isVisible) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().nameErrorPrivateConstant(module, name, this));
}
return constant;
}

@TruffleBoundary
@Specialization
protected RubyConstant lookupConstantUncached(RubyModule module, String name) {
RubyConstant constant = doLookup(module, name);
boolean isVisible = isVisible(module, constant);

if (!isVisible) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().nameErrorPrivateConstant(module, name, this));
}
return constant;
}

@Specialization(guards = "!isRubyModule(module)")
protected RubyConstant lookupNotModule(Object module, String name) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().typeErrorIsNotA(module.toString(), "class/module", this));
}

protected RubyConstant doLookup(RubyModule module, String name) {
return ModuleOperations.lookupConstant(getContext(), lexicalScope, module, name);
}

protected boolean isVisible(RubyModule module, RubyConstant constant) {
return constant == null || constant.isVisibleTo(getContext(), lexicalScope, module);
}

}
Original file line number Diff line number Diff line change
@@ -9,89 +9,77 @@
*/
package org.jruby.truffle.nodes.constants;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.dispatch.DispatchAction;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.MissingBehavior;
import org.jruby.truffle.nodes.literal.ObjectLiteralNode;
import org.jruby.truffle.runtime.LexicalScope;
import org.jruby.truffle.runtime.ModuleOperations;
import org.jruby.truffle.runtime.RubyConstant;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyModule;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;

public class ReadConstantNode extends RubyNode {

private final String name;
@Child private RubyNode receiver;
@Child private DispatchHeadNode dispatch;
@Child private GetConstantNode getConstantNode;

public ReadConstantNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, LexicalScope lexicalScope) {
super(context, sourceSection);
this.name = name;
this.receiver = receiver;
dispatch = new DispatchHeadNode(context, false, false, MissingBehavior.CALL_CONST_MISSING, lexicalScope, DispatchAction.READ_CONSTANT);

this.getConstantNode =
GetConstantNodeGen.create(context, sourceSection, receiver, new ObjectLiteralNode(context, sourceSection, name),
LookupConstantNodeGen.create(context, sourceSection, lexicalScope, null, null));
}

@Override
public Object execute(VirtualFrame frame) {
final Object receiverObject = receiver.execute(frame);

if (!(receiverObject instanceof RubyModule)) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().typeErrorIsNotA(receiverObject.toString(), "class/module", this));
}

return dispatch.dispatch(
frame,
receiverObject,
name,
null,
new Object[]{});
}

@Override
public void executeVoid(VirtualFrame frame) {
return getConstantNode.execute(frame);
}

@Override
public Object isDefined(VirtualFrame frame) {
CompilerDirectives.transferToInterpreter();

RubyNode receiver = getConstantNode.getModule();
final RubyContext context = getContext();

if (name.equals("Encoding")) {
/*
* Work-around so I don't have to load the iconv library - runners/formatters/junit.rb.
*/
// Work-around so I don't have to load the iconv library - runners/formatters/junit.rb.
return context.makeString("constant");
}

Object receiverObject;

final Object receiverObject;
try {
receiverObject = receiver.execute(frame);
} catch (RaiseException e) {
/*
* If we are looking up a constant in a constant that is itself undefined, we return Nil
* rather than raising the error. Eg.. defined?(Defined::Undefined1::Undefined2)
*/

/* If we are looking up a constant in a constant that is itself undefined, we return Nil
* rather than raising the error. Eg.. defined?(Defined::Undefined1::Undefined2).
*
* We should maybe try to see if receiver.isDefined() but we also need its value if it is,
* and we do not want to execute receiver twice. */
if (e.getRubyException().getLogicalClass() == context.getCoreLibrary().getNameErrorClass()) {
return nil();
}

throw e;
}

RubyModule module = (RubyModule) receiverObject; // TODO(cs): cast
RubyConstant constant = ModuleOperations.lookupConstant(context, dispatch.getLexicalScope(), module, name);
final RubyConstant constant;
try {
constant = getConstantNode.getLookupConstantNode().executeLookupConstant(frame, receiverObject, name);
} catch (RaiseException e) {
if (e.getRubyException().getLogicalClass() == context.getCoreLibrary().getTypeErrorClass()) {
// module is not a class/module
return nil();
} else if (e.getRubyException().getLogicalClass() == context.getCoreLibrary().getNameErrorClass()) {
// private constant
return nil();
}
throw e;
}

if (constant == null || !constant.isVisibleTo(context, dispatch.getLexicalScope(), module)) {
if (constant == null) {
return nil();
} else {
return context.makeString("constant");
Original file line number Diff line number Diff line change
@@ -31,6 +31,14 @@ public final class SequenceNode extends RubyNode {

@Children private final RubyNode[] body;

public static RubyNode sequenceNoFlatten(RubyContext context, SourceSection sourceSection, RubyNode... sequence) {
return new SequenceNode(context, sourceSection, sequence);
}

public static RubyNode sequenceNoFlatten(RubyContext context, SourceSection sourceSection, List<RubyNode> sequence) {
return sequenceNoFlatten(context, sourceSection, sequence.toArray(new RubyNode[sequence.size()]));
}

public static RubyNode sequence(RubyContext context, SourceSection sourceSection, RubyNode... sequence) {
return sequence(context, sourceSection, Arrays.asList(sequence));
}
@@ -93,4 +101,7 @@ public void executeVoid(VirtualFrame frame) {
}
}

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

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.object.*;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.truffle.nodes.objects.Allocator;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.UndefinedPlaceholder;
import org.jruby.truffle.runtime.core.*;

import java.math.BigDecimal;
import java.math.MathContext;
import java.util.EnumSet;

@CoreClass(name = "Truffle::BigDecimal")
public abstract class BigDecimalNodes {

private static final HiddenKey VALUE_IDENTIFIER = new HiddenKey("value");
private static final DynamicObjectFactory BIG_DECIMAL_FACTORY;
public static final Property VALUE_PROPERTY;

static {
Shape.Allocator allocator = RubyBasicObject.LAYOUT.createAllocator();
VALUE_PROPERTY = Property.create(
VALUE_IDENTIFIER,
allocator.locationForType(BigDecimal.class, EnumSet.of(LocationModifier.NonNull)),
0);
Shape shape = RubyBasicObject.EMPTY_SHAPE.addProperty(VALUE_PROPERTY);
BIG_DECIMAL_FACTORY = shape.createFactory();
}

// TODO (pitr 15-May-2015) figure out where to put RubyBigDecimal, or remove completely
public static class RubyBigDecimal extends RubyBasicObject {
public RubyBigDecimal(RubyClass rubyClass, DynamicObject dynamicObject) {
super(rubyClass, dynamicObject);
}
}

public static class RubyBigDecimalAllocator implements Allocator {

@Override
public RubyBasicObject allocate(RubyContext context, RubyClass rubyClass, Node currentNode) {
return createRubyBigDecimal(rubyClass, BigDecimal.ZERO);
}

}

public static BigDecimal getBigDecimalValue(RubyBasicObject bignum) {
assert bignum.getDynamicObject().getShape().hasProperty(VALUE_IDENTIFIER);
return (BigDecimal) VALUE_PROPERTY.get(bignum.getDynamicObject(), true);
}

public static void setBigDecimalValue(RubyBasicObject bignum, BigDecimal value) {
assert bignum.getDynamicObject().getShape().hasProperty(VALUE_IDENTIFIER);
VALUE_PROPERTY.setSafe(bignum.getDynamicObject(), value, null);
}

public static RubyBigDecimal createRubyBigDecimal(RubyClass rubyClass, BigDecimal value) {
return new RubyBigDecimal(rubyClass, BIG_DECIMAL_FACTORY.newInstance(value));
}

public abstract static class BigDecimalCoreMethodNode extends CoreMethodArrayArgumentsNode {

public BigDecimalCoreMethodNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public static boolean isRubyBigDecimal(Object value) {
return value instanceof RubyBigDecimal;
}
}

@CoreMethod(names = "initialize", required = 1)
public abstract static class InitializeNode extends BigDecimalCoreMethodNode {

public InitializeNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@Specialization(guards = "isRubyBigDecimal(v)")
public RubyBasicObject initialize(RubyBigDecimal self, RubyBasicObject v) {
return v;
}

@Specialization(guards = "isRubyString(v)")
public RubyBasicObject initializeFromString(RubyBigDecimal self, RubyBasicObject v) {
switch (v.toString()) {
case "NaN": // FIXME
case "Infinity": // FIXME
case "+Infinity": // FIXME
case "-Infinity": // FIXME
return self;
}

setBigDecimalValue(self, new BigDecimal(v.toString()));
return self;
}
}

// TODO: double specializations

@CoreMethod(names = "+", required = 1)
public abstract static class AdditionNode extends BigDecimalCoreMethodNode {

public AdditionNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@Specialization
public Object add(RubyBasicObject a, int b) {
return createRubyBigDecimal(
getContext().getCoreLibrary().getBigDecimalClass(),
getBigDecimalValue(a).add(BigDecimal.valueOf(b)));
}

@Specialization
public Object add(RubyBasicObject a, long b) {
return createRubyBigDecimal(
getContext().getCoreLibrary().getBigDecimalClass(),
getBigDecimalValue(a).add(BigDecimal.valueOf(b)));
}

@Specialization(guards = "isRubyBigDecimal(b)")
public Object add(RubyBasicObject a, RubyBasicObject b) {
return createRubyBigDecimal(
getContext().getCoreLibrary().getBigDecimalClass(),
getBigDecimalValue(a).add(getBigDecimalValue(b)));
}

}

@CoreMethod(names = "add", required = 2)
public abstract static class AddNode extends BigDecimalCoreMethodNode {

public AddNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@Specialization(guards = "isRubyBigDecimal(b)")
public Object add(RubyBasicObject a, RubyBasicObject b, int precision) {
return createRubyBigDecimal(
getContext().getCoreLibrary().getBigDecimalClass(),
getBigDecimalValue(a).add(getBigDecimalValue(b), new MathContext(precision)));
}

}

@CoreMethod(names = "-", required = 1)
public abstract static class SubtractNode extends BigDecimalCoreMethodNode {

public SubtractNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@Specialization
public Object subtract(RubyBasicObject a, int b) {
return createRubyBigDecimal(
getContext().getCoreLibrary().getBigDecimalClass(),
getBigDecimalValue(a).subtract(BigDecimal.valueOf(b)));
}

@Specialization
public Object subtract(RubyBasicObject a, long b) {
return createRubyBigDecimal(
getContext().getCoreLibrary().getBigDecimalClass(),
getBigDecimalValue(a).subtract(BigDecimal.valueOf(b)));
}

@Specialization(guards = "isRubyBigDecimal(b)")
public Object subtract(RubyBasicObject a, RubyBasicObject b) {
return createRubyBigDecimal(
getContext().getCoreLibrary().getBigDecimalClass(),
getBigDecimalValue(a).subtract(getBigDecimalValue(b)));
}

}

@CoreMethod(names = "sub", required = 2)
public abstract static class SubNode extends BigDecimalCoreMethodNode {

public SubNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@Specialization(guards = "isRubyBigDecimal(b)")
public Object sub(RubyBasicObject a, RubyBasicObject b, int precision) {
return createRubyBigDecimal(
getContext().getCoreLibrary().getBigDecimalClass(),
getBigDecimalValue(a).subtract(getBigDecimalValue(b), new MathContext(precision)));
}
}

@CoreMethod(names = {"==", "eql?"}, required = 1)
public abstract static class EqualNode extends BigDecimalCoreMethodNode {

public EqualNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@Specialization
public boolean equal(RubyBasicObject a, int b) {
return getBigDecimalValue(a).compareTo(BigDecimal.valueOf(b)) == 0;
}

@Specialization
public boolean equal(RubyBasicObject a, long b) {
return getBigDecimalValue(a).compareTo(BigDecimal.valueOf(b)) == 0;
}

@Specialization(guards = "isRubyBigDecimal(b)")
public boolean equal(RubyBasicObject a, RubyBasicObject b) {
return getBigDecimalValue(a).compareTo(getBigDecimalValue(b)) == 0;
}

}

@CoreMethod(names = {"to_s", "inspect"})
public abstract static class ToSNode extends CoreMethodArrayArgumentsNode {

public ToSNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@CompilerDirectives.TruffleBoundary
@Specialization
public RubyString toS(RubyBasicObject value) {
return getContext().makeString(getBigDecimalValue(value).toString());
}

}

}
Original file line number Diff line number Diff line change
@@ -960,16 +960,19 @@ public RubyProc proc(RubyProc block) {
}
}

@CoreMethod(names = "load", isModuleFunction = true, required = 1)
@CoreMethod(names = "load", isModuleFunction = true, required = 1, optional = 1)
public abstract static class LoadNode extends CoreMethodArrayArgumentsNode {

public LoadNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@TruffleBoundary
@Specialization
public boolean load(RubyString file) {
CompilerDirectives.transferToInterpreter();
public boolean load(RubyString file, boolean wrap) {
if (wrap) {
throw new UnsupportedOperationException();
}

try {
getContext().loadFile(file.toString(), this);
@@ -986,6 +989,11 @@ public boolean load(RubyString file) {

return true;
}

@Specialization
public boolean load(RubyString file, UndefinedPlaceholder wrap) {
return load(file, false);
}
}

@CoreMethod(names = "local_variables", needsSelf = false)
@@ -1315,6 +1323,13 @@ public boolean require(RubyString feature) {
throw new RaiseException(getContext().getCoreLibrary().loadErrorCannotLoad(feature.toString(), this));
}

// TODO CS 19-May-15 securerandom will use openssl if it's there, but we've only shimmed it

if (feature.toString().equals("openssl") && Truffle.getRuntime().getCallerFrame().getCallNode()
.getEncapsulatingSourceSection().getSource().getName().endsWith("securerandom.rb")) {
throw new RaiseException(getContext().getCoreLibrary().loadErrorCannotLoad(feature.toString(), this));
}

try {
getContext().getFeatureManager().require(feature.toString(), this);
} catch (IOException e) {
83 changes: 55 additions & 28 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/ModuleNodes.java
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@

import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.dsl.CreateCast;
import com.oracle.truffle.api.dsl.NodeChild;
@@ -36,7 +37,11 @@
import org.jruby.truffle.nodes.cast.BooleanCastNodeGen;
import org.jruby.truffle.nodes.coerce.SymbolOrToStrNode;
import org.jruby.truffle.nodes.coerce.SymbolOrToStrNodeGen;
import org.jruby.truffle.nodes.coerce.ToStrNode;
import org.jruby.truffle.nodes.coerce.ToStrNodeGen;
import org.jruby.truffle.nodes.constants.GetConstantNode;
import org.jruby.truffle.nodes.constants.GetConstantNodeGen;
import org.jruby.truffle.nodes.constants.LookupConstantNodeGen;
import org.jruby.truffle.nodes.control.SequenceNode;
import org.jruby.truffle.nodes.core.KernelNodes.BindingNode;
import org.jruby.truffle.nodes.core.ModuleNodesFactory.SetMethodVisibilityNodeGen;
@@ -572,6 +577,7 @@ public abstract static class ClassEvalNode extends CoreMethodArrayArgumentsNode

@Child private YieldDispatchHeadNode yield;
@Child private BindingNode bindingNode;
@Child private ToStrNode toStrNode;

public ClassEvalNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
@@ -586,32 +592,45 @@ protected RubyBinding getCallerBinding(VirtualFrame frame) {
return bindingNode.executeRubyBinding(frame);
}

protected RubyString toStr(VirtualFrame frame, Object object) {
if (toStrNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
toStrNode = insert(ToStrNodeGen.create(getContext(), getSourceSection(), null));
}
return toStrNode.executeRubyString(frame, object);
}

@Specialization
public Object classEval(VirtualFrame frame, RubyModule module, RubyString code, UndefinedPlaceholder file, UndefinedPlaceholder line, UndefinedPlaceholder block) {
CompilerDirectives.transferToInterpreter();

final Source source = Source.fromText(code.toString(), "(eval)");
return classEvalSource(frame, module, source, code.getByteList().getEncoding());
return classEvalSource(frame, module, code, "(eval)");
}

@Specialization
public Object classEval(VirtualFrame frame, RubyModule module, RubyString code, RubyString file, UndefinedPlaceholder line, UndefinedPlaceholder block) {
CompilerDirectives.transferToInterpreter();

final Source source = Source.fromNamedText(code.toString(), file.toString());
return classEvalSource(frame, module, source, code.getByteList().getEncoding());
return classEvalSource(frame, module, code, file.toString());
}

@Specialization
public Object classEval(VirtualFrame frame, RubyModule module, RubyString code, RubyString file, int line, UndefinedPlaceholder block) {
CompilerDirectives.transferToInterpreter();
return classEvalSource(frame, module, code, file.toString());
}

@Specialization(guards = "!isUndefinedPlaceholder(code)")
public Object classEval(VirtualFrame frame, RubyModule module, Object code, UndefinedPlaceholder file, UndefinedPlaceholder line, UndefinedPlaceholder block) {
return classEvalSource(frame, module, toStr(frame, code), file.toString());
}

final Source source = Source.fromNamedText(code.toString(), file.toString());
return classEvalSource(frame, module, source, code.getByteList().getEncoding());
@Specialization(guards = "!isUndefinedPlaceholder(file)")
public Object classEval(VirtualFrame frame, RubyModule module, RubyString code, Object file, UndefinedPlaceholder line, UndefinedPlaceholder block) {
return classEvalSource(frame, module, code, toStr(frame, file).toString());
}

private Object classEvalSource(VirtualFrame frame, RubyModule module, Source source, Encoding encoding) {
private Object classEvalSource(VirtualFrame frame, RubyModule module, RubyString code, String file) {
RubyBinding binding = getCallerBinding(frame);
Encoding encoding = code.getByteList().getEncoding();

CompilerDirectives.transferToInterpreter();
Source source = Source.fromText(code.toString(), file);

return getContext().execute(source, encoding, TranslatorDriver.ParserContext.MODULE, module, binding.getFrame(), this, new NodeWrapper() {
@Override
@@ -629,13 +648,18 @@ public Object classEval(VirtualFrame frame, RubyModule self, UndefinedPlaceholde
@Specialization
public Object classEval(RubyModule self, UndefinedPlaceholder code, UndefinedPlaceholder file, UndefinedPlaceholder line, UndefinedPlaceholder block) {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(getContext().getCoreLibrary().argumentError(0, 1, 2, this));
}

@Specialization(guards = "!isUndefinedPlaceholder(code)")
public Object classEval(RubyModule self, Object code, UndefinedPlaceholder file, UndefinedPlaceholder line, RubyProc block) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError(1, 0, this));
}

}

@CoreMethod(names = {"class_exec","module_exec"}, argumentsAsArray = true, needsBlock = true)
@CoreMethod(names = { "class_exec", "module_exec" }, argumentsAsArray = true, needsBlock = true)
public abstract static class ClassExecNode extends CoreMethodArrayArgumentsNode {

@Child private YieldDispatchHeadNode yield;
@@ -649,11 +673,13 @@ public ClassExecNode(RubyContext context, SourceSection sourceSection) {

@Specialization
public Object classExec(VirtualFrame frame, RubyModule self, Object[] args, RubyProc block) {
CompilerDirectives.transferToInterpreter();

// TODO: deal with args
return yield.dispatchWithModifiedSelf(frame, block, self, args);
}

return yield.dispatchWithModifiedSelf(frame, block, self);
@Specialization
public Object classExec(VirtualFrame frame, RubyModule self, Object[] args, UndefinedPlaceholder block) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().noBlockGiven(this));
}

}
@@ -823,11 +849,12 @@ public boolean isConstDefined(RubyModule module, String fullName, boolean inheri
})
public abstract static class ConstGetNode extends CoreMethodNode {

@Child private DispatchHeadNode dispatch;
@Child private GetConstantNode getConstantNode;

public ConstGetNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
dispatch = new DispatchHeadNode(context, false, false, MissingBehavior.CALL_CONST_MISSING, null, DispatchAction.READ_CONSTANT);
this.getConstantNode = GetConstantNodeGen.create(context, sourceSection, null, null,
LookupConstantNodeGen.create(context, sourceSection, LexicalScope.NONE, null, null));
}

@CreateCast("name")
@@ -840,17 +867,12 @@ public Object getConstant(VirtualFrame frame, RubyModule module, String name, Un
return getConstant(frame, module, name, true);
}

@Specialization(guards = "isScoped(name)")
public Object getConstantScoped(VirtualFrame frame, RubyModule module, String name, UndefinedPlaceholder inherit) {
return getConstantScoped(frame, module, name, true);
}

@Specialization(guards = { "isTrue(inherit)", "!isScoped(name)" })
@Specialization(guards = { "!isScoped(name)", "inherit" })
public Object getConstant(VirtualFrame frame, RubyModule module, String name, boolean inherit) {
return dispatch.dispatch(frame, module, name, null, new Object[] {});
return getConstantNode.executeGetConstant(frame, module, name);
}

@Specialization(guards = { "!isTrue(inherit)", "!isScoped(name)" })
@Specialization(guards = { "!isScoped(name)", "!inherit" })
public Object getConstantNoInherit(VirtualFrame frame, RubyModule module, String name, boolean inherit) {
CompilerDirectives.transferToInterpreter();

@@ -863,6 +885,11 @@ public Object getConstantNoInherit(VirtualFrame frame, RubyModule module, String
}
}

@Specialization(guards = "isScoped(fullName)")
public Object getConstantScoped(VirtualFrame frame, RubyModule module, String fullName, UndefinedPlaceholder inherit) {
return getConstantScoped(frame, module, fullName, true);
}

@Specialization(guards = "isScoped(fullName)")
public Object getConstantScoped(VirtualFrame frame, RubyModule module, String fullName, boolean inherit) {
CompilerDirectives.transferToInterpreter();
Original file line number Diff line number Diff line change
@@ -27,14 +27,12 @@ public class CachedBooleanDispatchNode extends CachedDispatchNode {
private final InternalMethod falseMethod;
private final BranchProfile falseProfile = BranchProfile.create();

private final Object falseValue;
@Child private DirectCallNode falseCallDirect;

private final Assumption trueUnmodifiedAssumption;
private final InternalMethod trueMethod;
private final BranchProfile trueProfile = BranchProfile.create();

private final Object trueValue;
@Child private DirectCallNode trueCallDirect;

@Child private IndirectCallNode indirectCallNode;
@@ -55,7 +53,6 @@ public CachedBooleanDispatchNode(

this.falseUnmodifiedAssumption = falseUnmodifiedAssumption;
this.falseMethod = falseMethod;
this.falseValue = falseValue;

if (falseMethod != null) {
if (!indirect) {
@@ -70,7 +67,6 @@ public CachedBooleanDispatchNode(

this.trueUnmodifiedAssumption = trueUnmodifiedAssumption;
this.trueMethod = trueMethod;
this.trueValue = trueValue;

if (trueMethod != null) {
if (!indirect) {
@@ -151,9 +147,6 @@ public Object executeDispatch(
case RESPOND_TO_METHOD:
return true;

case READ_CONSTANT:
return trueValue;

default:
throw new UnsupportedOperationException();
}
@@ -199,9 +192,6 @@ public Object executeDispatch(
case RESPOND_TO_METHOD:
return true;

case READ_CONSTANT:
return falseValue;

default:
throw new UnsupportedOperationException();

Original file line number Diff line number Diff line change
@@ -27,8 +27,6 @@ public class CachedBoxedDispatchNode extends CachedDispatchNode {
private final RubyClass expectedClass;
private final Assumption unmodifiedAssumption;

private final Object value;

private final InternalMethod method;
@Child private DirectCallNode callNode;
@Child private IndirectCallNode indirectCallNode;
@@ -38,41 +36,14 @@ public CachedBoxedDispatchNode(
Object cachedName,
DispatchNode next,
RubyClass expectedClass,
Object value,
InternalMethod method,
boolean indirect,
DispatchAction dispatchAction) {
this(
context,
cachedName,
next,
expectedClass,
expectedClass.getUnmodifiedAssumption(),
value,
method,
indirect,
dispatchAction);
}

/**
* Allows to give the assumption, which is different than the expectedClass assumption for constant lookup.
*/
public CachedBoxedDispatchNode(
RubyContext context,
Object cachedName,
DispatchNode next,
RubyClass expectedClass,
Assumption unmodifiedAssumption,
Object value,
InternalMethod method,
boolean indirect,
DispatchAction dispatchAction) {
super(context, cachedName, next, indirect, dispatchAction);

this.expectedClass = expectedClass;
this.unmodifiedAssumption = unmodifiedAssumption;
this.unmodifiedAssumption = expectedClass.getUnmodifiedAssumption();
this.next = next;
this.value = value;
this.method = method;

if (method != null) {
@@ -155,9 +126,6 @@ public Object executeDispatch(
case RESPOND_TO_METHOD:
return true;

case READ_CONSTANT:
return value;

default:
throw new UnsupportedOperationException();
}
Original file line number Diff line number Diff line change
@@ -145,29 +145,6 @@ public Object executeDispatch(
case RESPOND_TO_METHOD:
return false;

case READ_CONSTANT: {
if (isIndirect()) {
return indirectCallNode.call(
frame,
method.getCallTarget(),
RubyArguments.pack(
method,
method.getDeclarationFrame(),
receiverObject,
(RubyProc) blockObject,
new Object[]{getCachedNameAsSymbol()}));
} else {
return callNode.call(
frame,
RubyArguments.pack(
method,
method.getDeclarationFrame(),
receiverObject,
(RubyProc) blockObject,
new Object[]{getCachedNameAsSymbol()}));
}
}

default:
throw new UnsupportedOperationException();
}
Original file line number Diff line number Diff line change
@@ -25,8 +25,6 @@ public class CachedBoxedSymbolDispatchNode extends CachedDispatchNode {

private final Assumption unmodifiedAssumption;

private final Object value;

private final InternalMethod method;
@Child private DirectCallNode callNode;
@Child private IndirectCallNode indirectCallNode;
@@ -35,14 +33,12 @@ public CachedBoxedSymbolDispatchNode(
RubyContext context,
Object cachedName,
DispatchNode next,
Object value,
InternalMethod method,
boolean indirect,
DispatchAction dispatchAction) {
super(context, cachedName, next, indirect, dispatchAction);

unmodifiedAssumption = context.getCoreLibrary().getSymbolClass().getUnmodifiedAssumption();
this.value = value;
this.method = method;

if (method != null) {
@@ -121,9 +117,6 @@ public Object executeDispatch(
case RESPOND_TO_METHOD:
return true;

case READ_CONSTANT:
return value;

default:
throw new UnsupportedOperationException();
}
Loading

0 comments on commit c40d698

Please sign in to comment.