Skip to content

Commit

Permalink
Showing 344 changed files with 4,495 additions and 2,404 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -70,6 +70,7 @@ lib/ruby/stdlib/readline*
lib/ruby/stdlib/minitest*
lib/ruby/stdlib/power_assert*
lib/ruby/stdlib/psych*
lib/ruby/stdlib/**/maven-metadata-local.xml
release.properties
share
spaces test
3 changes: 3 additions & 0 deletions bin/jruby-truffle
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash

$(dirname $BASH_SOURCE[0])/jruby -X+T $@
2 changes: 1 addition & 1 deletion ci.hocon
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@ graal-vm: {
downloads: {
GRAALVM_DIR: {
name: graalvm-release,
version: "0.15",
version: "0.16",
platformspecific: true
}
}
14 changes: 11 additions & 3 deletions core/src/main/java/org/jruby/runtime/Visibility.java
Original file line number Diff line number Diff line change
@@ -29,15 +29,23 @@ public enum Visibility {
PUBLIC, PROTECTED, PRIVATE, MODULE_FUNCTION;

private static final Visibility[] VALUES = values();
public boolean isPrivate() {
return this == PRIVATE;

public boolean isPublic() {
return this == PUBLIC;
}

public boolean isProtected() {
return this == PROTECTED;
}

public boolean isPrivate() {
return this == PRIVATE;
}

public boolean isModuleFunction() {
return this == MODULE_FUNCTION;
}

public static Visibility[] getValues() {
return VALUES;
}
3 changes: 2 additions & 1 deletion core/src/main/java/org/jruby/util/cli/Options.java
Original file line number Diff line number Diff line change
@@ -242,7 +242,7 @@ public class Options {
public static final Option<Boolean> TRUFFLE_COVERAGE_GLOBAL = bool(TRUFFLE, "truffle.coverage.global", false, "Run coverage for all code and print results on exit.");

public static final Option<String> TRUFFLE_CORE_LOAD_PATH = string(TRUFFLE, "truffle.core.load_path", "truffle:/jruby-truffle", "Location to load the Truffle core library from.");
public static final Option<Boolean> TRUFFLE_CORE_PARALLEL_LOAD = bool(TRUFFLE, "truffle.core.parallel_load", true, "Load the Truffle core library in parallel.");
public static final Option<Boolean> TRUFFLE_CORE_PARALLEL_LOAD = bool(TRUFFLE, "truffle.core.parallel_load", false, "Load the Truffle core library in parallel.");

public static final Option<Integer> TRUFFLE_ARRAY_UNINITIALIZED_SIZE = integer(TRUFFLE, "truffle.array.uninitialized_size", 32, "How large an Array to allocate when we have no other information to go on.");
public static final Option<Integer> TRUFFLE_ARRAY_SMALL = integer(TRUFFLE, "truffle.array.small", 3, "Maximum size of an Array to consider small for optimisations.");
@@ -306,6 +306,7 @@ public class Options {
public static final Option<Boolean> TRUFFLE_METRICS_MEMORY_USED_ON_EXIT = bool(TRUFFLE, "truffle.metrics.memory_used_on_exit", false, "Print the size of heap memory in use on exit.");
public static final Option<Boolean> TRUFFLE_CALL_GRAPH = bool(TRUFFLE, "truffle.callgraph", false, "Maintain a call graph.");
public static final Option<String> TRUFFLE_CALL_GRAPH_WRITE = string(TRUFFLE, "truffle.callgraph.write", "File to write the call garph to on exit.");
public static final Option<Boolean> TRUFFLE_CHAOS = bool(TRUFFLE, "truffle.chaos", false, "Randomly modify the representation of objects.");

public static final Option<Boolean> TRUFFLE_GRAAL_WARNING_UNLESS = bool(TRUFFLE, "truffle.graal.warn_unless", true, "Warn unless the JVM has the Graal compiler.");
public static final Option<Boolean> TRUFFLE_PERF_WARNING = bool(TRUFFLE, "truffle.perf.warn", false, "Warn when using a fature which is not optimized yet.");
2 changes: 1 addition & 1 deletion lib/pom.rb
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ class Gem::Installer
def say(message)
if message != spec.post_install_message || !MORE_QUIET
super
end
end
end
end
end
14 changes: 7 additions & 7 deletions lib/ruby/truffle/cext/ruby.h
Original file line number Diff line number Diff line change
@@ -52,11 +52,7 @@ extern "C" {

// Basic types

#ifdef JT_INT_VALUE
typedef uintptr_t VALUE;
#else
typedef void *VALUE;
#endif
typedef void *VALUE;

typedef VALUE ID;

@@ -420,7 +416,7 @@ VALUE rb_class_real(VALUE ruby_class);
VALUE rb_class_superclass(VALUE ruby_class);
VALUE rb_class_of(VALUE object);
VALUE rb_obj_class(VALUE object);
#define CLASS_OF(object) rb_class_of((VALUE) (object))
VALUE CLASS_OF(VALUE object);
VALUE rb_obj_alloc(VALUE ruby_class);
VALUE rb_class_path(VALUE ruby_class);
VALUE rb_path2class(const char *string);
@@ -522,7 +518,7 @@ void rb_undef(VALUE module, ID name);

void rb_attr(VALUE ruby_class, ID name, int read, int write, int ex);

typedef VALUE (*rb_alloc_func_t)(VALUE);
typedef VALUE (*rb_alloc_func_t)(VALUE ruby_class);
void rb_define_alloc_func(VALUE ruby_class, rb_alloc_func_t alloc_function);

// Mutexes
@@ -680,6 +676,10 @@ VALUE *rb_ruby_verbose_ptr(void);
VALUE *rb_ruby_debug_ptr(void);
#define ruby_debug (*rb_ruby_debug_ptr())

// Non-standard

NORETURN(void rb_jt_error(const char *message));

#if defined(__cplusplus)
}
#endif
88 changes: 74 additions & 14 deletions lib/ruby/truffle/jruby+truffle/lib/truffle/config.rb
Original file line number Diff line number Diff line change
@@ -174,6 +174,14 @@ def exclusion_file(gem_name)
data.pretty_inspect
end

def exclusions_for(name)
{ setup: { file: { 'excluded-tests.rb' => format(dedent(<<-RUBY), exclusion_file(name)) } } }
failures = %s
require 'truffle/exclude_rspec_examples'
Truffle.exclude_rspec_examples failures
RUBY
end

rails_common =
deep_merge replacements.fetch(:bundler),
stubs.fetch(:kernel_gem),
@@ -198,12 +206,13 @@ def exclusion_file(gem_name)
deep_merge(
rails_common,
stubs.fetch(:html_sanitizer),
setup: { file: { 'excluded-tests.rb' => format(dedent(<<-RUBY), exclusion_file(:actionpack)),
failures = %s
require 'truffle/exclude_rspec_examples'
Truffle.exclude_rspec_examples failures
RUBY
} })
exclusions_for(:actionpack))

Truffle::Runner.add_config :railties,
deep_merge(rails_common,
stubs.fetch(:activesupport_isolation),
exclusions_for(:railties),
run: { require: %w[bundler.rb] })

Truffle::Runner.add_config :'concurrent-ruby',
setup: { file: { "stub-processor_number.rb" => dedent(<<-RUBY) } },
@@ -235,27 +244,28 @@ def compute_physical_processor_count


class Truffle::Runner::CIEnvironment
def rails_ci
declare_options debug: ['--[no-]debug', 'Run tests with remote debugging enabled.',
STORE_NEW_VALUE, false],
exclude: ['--[no-]exclude', 'Exclude known failing tests',
STORE_NEW_VALUE, true]
def rails_ci(has_exclusions: false, skip_test_files: [])
options = {}
options[:debug] = ['-d', '--[no-]debug', 'Run tests with remote debugging enabled.', STORE_NEW_VALUE, false]
options[:exclude] = ['--[no-]exclusion', 'Exclude known failing tests', STORE_NEW_VALUE, true] if has_exclusions

declare_options options
repository_name 'rails'

use_only_https_git_paths!

has_to_succeed setup
set_result run([*%w[--require-pattern test/**/*_test.rb],
*(%w[-r excluded-tests] if option(:exclude)),
set_result run([*(['--exclude-pattern', *skip_test_files.join('|')] unless skip_test_files.empty?),
*%w[--require-pattern test/**/*_test.rb],
*(%w[-r excluded-tests] if has_exclusions && option(:exclude)),
*(%w[--debug] if option(:debug)),
*%w[-- -I test -e nil]])
end
end

Truffle::Runner.add_ci_definition :actionpack do
subdir 'actionpack'
rails_ci
rails_ci has_exclusions: true
end

Truffle::Runner.add_ci_definition :activemodel do
@@ -268,6 +278,56 @@ def rails_ci
rails_ci
end

Truffle::Runner.add_ci_definition :railties do
subdir 'railties'
rails_ci has_exclusions: true,
skip_test_files: %w[
test/application/asset_debugging_test.rb
test/application/assets_test.rb
test/application/bin_setup_test.rb
test/application/configuration_test.rb
test/application/console_test.rb
test/application/generators_test.rb
test/application/loading_test.rb
test/application/mailer_previews_test.rb
test/application/middleware_test.rb
test/application/multiple_applications_test.rb
test/application/paths_test.rb
test/application/rackup_test.rb
test/application/rake_test.rb
test/application/rendering_test.rb
test/application/routing_test.rb
test/application/runner_test.rb
test/application/test_runner_test.rb
test/application/test_test.rb
test/application/url_generation_test.rb
test/application/configuration/base_test.rb
test/application/configuration/custom_test.rb
test/application/initializers/frameworks_test.rb
test/application/initializers/hooks_test.rb
test/application/initializers/i18n_test.rb
test/application/initializers/load_path_test.rb
test/application/initializers/notifications_test.rb
test/application/middleware/cache_test.rb
test/application/middleware/cookies_test.rb
test/application/middleware/exceptions_test.rb
test/application/middleware/remote_ip_test.rb
test/application/middleware/sendfile_test.rb
test/application/middleware/session_test.rb
test/application/middleware/static_test.rb
test/application/rack/logger_test.rb
test/application/rake/dbs_test.rb
test/application/rake/migrations_test.rb
test/application/rake/notes_test.rb
test/railties/engine_test.rb
test/railties/generators_test.rb
test/railties/mounted_engine_test.rb
test/railties/railtie_test.rb
test/fixtures
test/rails_info_controller_test
test/commands/console_test]
end

Truffle::Runner.add_ci_definition :algebrick do

has_to_succeed setup
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
---
PathGenerationTest:
- test_original_script_name
Rails::TestInfoTest:
- test_with_file
- test_with_opts
Rails::DBConsoleTest:
- test_sqlite3_db_without_defined_rails_root
ActionsTest:
- test_environment_should_include_data_in_environment_initializer_block_with_env_option
AppGeneratorTest:
- test_application_name_is_detected_if_it_exists_and_app_folder_renamed
- test_application_name_with_spaces
- test_application_new_exits_with_message_and_non_zero_code_when_generating_inside_existing_rails_directory
- test_application_new_show_help_message_inside_existing_rails_directory
- test_assets
- test_generator_if_skip_sprockets_is_given
- test_generator_if_skip_turbolinks_is_given
- test_gitignore_when_sqlite3
- test_javascript_is_skipped_if_required
- test_jquery_is_the_default_javascript_library
- test_new_hash_style
- test_other_javascript_libraries
- test_rails_update_generates_correct_session_key
- test_spring
- test_template_is_executed_when_supplied
- test_template_is_executed_when_supplied_an_https_path
- test_web_console
GeneratorGeneratorTest:
- test_generator_skeleton_is_created
- test_generator_skeleton_is_created_without_file_name_namespace
- test_namespaced_generator_skeleton
- test_namespaced_generator_skeleton_without_file_name_namespace
Rails::Generators::GeneratorTest:
- test_filter
- test_two_filters
NamespacedScaffoldGeneratorTest:
- test_scaffold_with_namespace_on_invoke
- test_scaffold_with_namespace_on_revoke
- test_scaffold_with_nested_namespace_on_invoke
- test_scaffold_with_nested_namespace_on_revoke
OrmTest:
- test_orm_instance_returns_orm_class_instance_with_name
PluginGeneratorTest:
- test_create_mountable_application_with_mountable_option
- test_creating_engine_in_full_mode
- test_ensure_that_migration_tasks_work_with_mountable_option
- test_ensure_that_tests_work
- test_ensure_that_tests_works_in_full_mode
- test_generating_controller_inside_mountable_engine
- test_generation_runs_bundle_install_with_full_and_mountable
- test_shebang
- test_shebang_is_added_to_rails_file
- test_shebang_when_is_the_same_as_default_use_env
- test_template_is_executed_when_supplied
- test_template_is_executed_when_supplied_an_https_path
- test_usage_of_engine_commands
ResourceGeneratorTest:
- test_files_from_inherited_invocation
- test_inherited_invocations_with_attributes
- test_plural_names_are_singularized
- test_plural_names_can_be_forced
- test_resource_controller_with_actions
- test_resource_controller_with_pluralized_class_name
ScaffoldControllerGeneratorTest:
- test_controller_permit_polymorphic_references_attributes
- test_controller_permit_references_attributes
- test_controller_skeleton_is_created
- test_controller_tests_pass_by_default_inside_full_engine
- test_controller_tests_pass_by_default_inside_mountable_engine
- test_customized_orm_is_used
- test_default_orm_is_used
- test_dont_use_require_or_permit_if_there_are_no_attributes
- test_functional_tests
- test_functional_tests_without_attributes
- test_helper_are_invoked_with_a_pluralized_name
- test_index_page_have_notice
- test_views_are_generated
ScaffoldGeneratorTest:
- test_functional_tests_without_attributes
- test_scaffold_generator_belongs_to
- test_scaffold_generator_no_javascripts
- test_scaffold_generator_no_stylesheets
- test_scaffold_generator_outputs_error_message_on_missing_attribute_type
- test_scaffold_generator_password_digest
- test_scaffold_on_invoke
- test_scaffold_tests_pass_by_default_inside_full_engine
- test_scaffold_tests_pass_by_default_inside_mountable_engine
- test_scaffold_with_namespace_on_invoke
- test_scaffold_with_namespace_on_revoke
GeneratorsTest:
- test_rails_root_templates
32 changes: 18 additions & 14 deletions lib/ruby/truffle/jruby+truffle/lib/truffle/runner.rb
Original file line number Diff line number Diff line change
@@ -65,7 +65,7 @@ def print_cmd(cmd, dir, print)
cmd = Array(cmd) # wrap if it's just a string

formatted_env, command = if cmd[0].is_a?(Hash)
[cmd[0].map { |k, v| "#{k}=#{v}" }, cmd[1..-1]]
[cmd[0].map { |k, v| "#{k}=\"#{v}\"" }, cmd[1..-1]]
else
[[], cmd]
end
@@ -198,7 +198,7 @@ module OptionBlocks

begin
apply_pattern = -> (pattern, old, options) do
Dir.glob(pattern) do |file|
Dir.glob(pattern).sort.each do |file|
if options[:exclude_pattern].any? { |p| /#{p}/ =~ file }
puts "skipped: #{file}"
next
@@ -370,7 +370,7 @@ def initialize(argv, options = {})
@gem_name = if @options[:global][:configuration]
@options[:global][:configuration].to_sym
else
candidates = Dir['*.gemspec']
candidates = Dir['*.gemspec'].sort
if candidates.size == 1
gem_name, _ = candidates.first.split('.')
gem_name.to_sym
@@ -518,7 +518,7 @@ def gemfile_use_path!(gems_path)
gem_name, options = parse_gemfile_line(line)
repo_name = options[:git].split('/').last
repo_match = "#{gems_path}/bundler/gems/#{repo_name}-*"
repo_path = Dir[repo_match].first
repo_path = Dir[repo_match].sort.first

["# Overridden by jtr\n",
'# ' + line,
@@ -623,7 +623,7 @@ def subcommand_run(rest)
end

executable = if @options[:run][:executable]
executables = Dir.glob("#{@options[:global][:truffle_bundle_path]}/jruby+truffle/*/gems/*/{bin,exe}/*")
executables = Dir.glob("#{@options[:global][:truffle_bundle_path]}/jruby+truffle/*/gems/*/{bin,exe}/*").sort
executables.find { |path| File.basename(path) == @options[:run][:executable] } or
raise "no executable with name '#{@options[:run][:executable]}' found"
end
@@ -637,27 +637,31 @@ def subcommand_run(rest)
'-X+T',
"-J-Xmx#{@options[:run][:xmx]}",
*(%w[-J-ea -J-esa] unless @options[:run][:no_asserts]),
("-Xtruffle.core.load_path=#{core_load_path}" if @options[:global][:use_fs_core] && !missing_core_load_path),
('-Xtruffle.exceptions.print_java=true' if @options[:run][:jexception])
*("-Xtruffle.core.load_path=#{core_load_path}" if @options[:global][:use_fs_core] && !missing_core_load_path),
*('-Xtruffle.exceptions.print_java=true' if @options[:run][:jexception])
]

bundler_setup = "./#{@options[:global][:truffle_bundle_path]}/bundler/setup.rb"
cmd_options = [
*(truffle_options unless @options[:run][:no_truffle]),
(format(@options[:global][:debug_option], @options[:global][:debug_port]) if @options[:run][:debug]),
jruby_options = [
*(format(@options[:global][:debug_option], @options[:global][:debug_port]) if @options[:run][:debug]),
*(truffle_options unless @options[:run][:no_truffle])
]

bundler_setup = File.expand_path "#{@options[:global][:truffle_bundle_path]}/bundler/setup.rb"
env_options = [
*ruby_options,
*(['-r', bundler_setup] if File.exist? bundler_setup),
*@options[:run][:load_path].flat_map { |v| ['-I', v] },
*@options[:run][:require].flat_map { |v| ['-r', v] }
].compact
]

env = @options[:run][:environment]
env['JAVACMD'] = @options[:global][:graal_path] if @options[:run][:graal]
env.each { |k, v| env[k] = v.to_s }

cmd = [(env unless env.empty?),
@options[:run][:interpreter_path].to_s,
*cmd_options,
*jruby_options,
*env_options,
executable,
*rest
].compact
@@ -688,7 +692,7 @@ def subcommand_ci(rest)
File.read(Pathname(@called_from_dir).join(path))
end
end
cis_to_run = YAML.load(batch_content)
cis_to_run = YAML.load(batch_content)

results = cis_to_run.map do |ci|
# ci is just a name or a array of name and options
93 changes: 67 additions & 26 deletions lib/ruby/truffle/truffle/digest.rb
Original file line number Diff line number Diff line change
@@ -6,18 +6,72 @@
# GNU General Public License version 2
# GNU Lesser General Public License version 2.1

# The part enclosed between START from MRI/END from MRI is licensed
# under LICENSE.RUBY as it is derived from lib/ruby/stdlib/digest.rb.

module Digest

NO_MESSAGE = Object.new
# START from MRI
class ::Digest::Class
# Creates a digest object and reads a given file, _name_.
# Optional arguments are passed to the constructor of the digest
# class.
#
# p Digest::SHA256.file("X11R6.8.2-src.tar.bz2").hexdigest
# # => "f02e3c85572dc9ad7cb77c2a638e3be24cc1b5bea9fdbb0b0299c9668475c534"
def self.file(name, *args)
new(*args).file(name)
end

class Class
# Returns the base64 encoded hash value of a given _string_. The
# return value is properly padded with '=' and contains no line
# feeds.
def self.base64digest(str, *args)
[digest(str, *args)].pack('m0')
end
end

def self.file(file)
digest = new
digest.update File.read(file)
digest
module Instance
# Updates the digest with the contents of a given file _name_ and
# returns self.
def file(name)
File.open(name, "rb") {|f|
buf = ""
while f.read(16384, buf)
update buf
end
}
self
end

# If none is given, returns the resulting hash value of the digest
# in a base64 encoded form, keeping the digest's state.
#
# If a +string+ is given, returns the hash value for the given
# +string+ in a base64 encoded form, resetting the digest to the
# initial state before and after the process.
#
# In either case, the return value is properly padded with '=' and
# contains no line feeds.
def base64digest(str = nil)
[str ? digest(str) : digest].pack('m0')
end

# Returns the resulting hash value and resets the digest to the
# initial state.
def base64digest!
[digest!].pack('m0')
end
end
# END from MRI

NO_MESSAGE = Object.new

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

class Class
def self.digest(message)
digest = new
digest.update message
@@ -29,18 +83,19 @@ def self.hexdigest(message)
digest.update message
digest.hexdigest
end
end

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

alias_method :<<, :update

def reset
Truffle::Digest.reset @digest
end

def digest(message=NO_MESSAGE)
def digest(message = NO_MESSAGE)
if NO_MESSAGE == message
Truffle::Digest.digest @digest
else
@@ -50,10 +105,9 @@ def digest(message=NO_MESSAGE)
end
end

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

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

@@ -72,7 +126,6 @@ def hexdigest!
def digest_length
Truffle::Digest.digest_length @digest
end

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

@@ -83,73 +136,61 @@ def ==(other)
def inspect
"#<#{self.class.name}: #{hexdigest}>"
end
end

class Class
include Instance
end

class MD5 < Class

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

def block_length
64
end

end

class SHA1 < Class

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

def block_length
64
end

end

class SHA256 < Class

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

def block_length
64
end

end

class SHA384 < Class

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

def block_length
128
end

end

class SHA512 < Class

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

def block_length
128
end

end

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

end

require 'digest/sha2'
2 changes: 1 addition & 1 deletion mx.jruby/suite.py
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ def mavenLib(mavenDep, sha1):
"suites": [
{
"name": "truffle",
"version": "0f666d1a0c4eabc0d44d1a2ad75cebd3ea6dbadb",
"version": "387cbe478688e84d211aa534b7b93d47709cadd9",
"urls": [
{"url": "https://github.com/graalvm/truffle.git", "kind": "git"},
{"url": "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind": "binary"},
9 changes: 7 additions & 2 deletions spec/ruby/core/kernel/backtick_spec.rb
Original file line number Diff line number Diff line change
@@ -19,6 +19,13 @@
`echo disc #{ip}`.should == "disc world\n"
end

it "lets the standard error stream pass through to the inherited stderr" do
cmd = ruby_cmd('STDERR.print "error stream"')
lambda {
`#{cmd}`.should == ""
}.should output_to_fd("error stream", STDERR)
end

it "produces a String in the default external encoding" do
Encoding.default_external = Encoding::SHIFT_JIS
`echo disc`.encoding.should equal(Encoding::SHIFT_JIS)
@@ -66,8 +73,6 @@
end

describe "Kernel.`" do
it "needs to be reviewed for spec completeness"

it "tries to convert the given argument to String using #to_str" do
(obj = mock('echo test')).should_receive(:to_str).and_return("echo test")
Kernel.`(obj).should == "test\n" #` fix vim syntax highlighting
1 change: 0 additions & 1 deletion spec/truffle/tags/core/argf/close_tags.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
slow:ARGF.close does not close STDIN
fails:ARGF.close does not close STDIN
fails:ARGF.close doesn't raise an IOError if called on a closed stream
1 change: 0 additions & 1 deletion spec/truffle/tags/core/argf/read_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
slow:ARGF.read reads the contents of stdin
slow:ARGF.read reads a number of bytes from stdin
slow:ARGF.read reads the contents of one file and stdin
fails:ARGF.read clears output buffer before appending to it

This file was deleted.

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/basicobject/superclass_tags.txt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,2 @@
fails:Binding#local_variable_defined? returns false when a variable is not defined
fails:Binding#local_variable_defined? returns true when a regular local variable is defined
fails:Binding#local_variable_defined? returns true when a local variable is defined using eval()
fails:Binding#local_variable_defined? returns true when a local variable is defined using Binding#local_variable_set
fails:Binding#local_variable_defined? returns true when a local variable is defined in a parent scope
fails:Binding#local_variable_defined? allows usage of a String as the variable name
fails:Binding#local_variable_defined? allows usage of an object responding to #to_str as the variable name
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/class/initialize_copy_tags.txt

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/core/class/initialize_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/class/new_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/class/to_s_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/dir/close_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/enumerable/chunk_tags.txt

This file was deleted.

4 changes: 0 additions & 4 deletions spec/truffle/tags/core/enumerable/chunk_while_tags.txt

This file was deleted.

4 changes: 0 additions & 4 deletions spec/truffle/tags/core/enumerable/max_tags.txt

This file was deleted.

4 changes: 0 additions & 4 deletions spec/truffle/tags/core/enumerable/min_tags.txt

This file was deleted.

5 changes: 0 additions & 5 deletions spec/truffle/tags/core/enumerable/slice_when_tags.txt

This file was deleted.

3 changes: 1 addition & 2 deletions spec/truffle/tags/core/file/ftype_tags.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
fails:File.ftype returns fifo when the file is a fifo
fails:File.ftype returns 'socket' when the file is a socket
fails:File::Stat#ftype returns fifo when the file is a fifo
slow:File.ftype returns fifo when the file is a fifo
3 changes: 0 additions & 3 deletions spec/truffle/tags/core/file/grpowned_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
fails:File.grpowned? takes non primary groups into account
fails(windows):File.grpowned? returns false if the file exist
fails:File.grpowned? accepts an object that has a #to_path method
fails:File.grpowned? returns true if the file exist
1 change: 0 additions & 1 deletion spec/truffle/tags/core/file/link_tags.txt

This file was deleted.

5 changes: 1 addition & 4 deletions spec/truffle/tags/core/file/open_tags.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
fails:File.open opens a file for binary read-write starting at the beginning of the file
fails:File.open raises a SystemCallError if passed an invalid Integer type
fails:File.open with a block does not raise error when file is closed inside the block
fails:File.open on a FIFO opens it as a normal file
fails:File.open opens a file with a file descriptor d and a block
fails:File.open with a block propagates StandardErrors produced by close
slow:File.open on a FIFO opens it as a normal file
2 changes: 1 addition & 1 deletion spec/truffle/tags/core/file/pipe_tags.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
fails:File.pipe? returns true if the file is a pipe
slow:File.pipe? returns true if the file is a pipe
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/file/reopen_tags.txt

This file was deleted.

2 changes: 1 addition & 1 deletion spec/truffle/tags/core/file/setgid_tags.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
fails:File.setgid? returns true when the gid bit is set
slow:File.setgid? returns true when the gid bit is set
2 changes: 1 addition & 1 deletion spec/truffle/tags/core/file/setuid_tags.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
fails:File.setuid? returns true when the gid bit is set
slow:File.setuid? returns true when the gid bit is set
1 change: 0 additions & 1 deletion spec/truffle/tags/core/file/size_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
fails:File#size raises an IOError on a closed file
windows:File.size? returns the size of the file if it exists and is not empty
windows:File.size? returns nil if file_name doesn't exist or has 0 size
windows:File.size? returns nil if file_name is empty
1 change: 0 additions & 1 deletion spec/truffle/tags/core/file/socket_tags.txt

This file was deleted.

2 changes: 1 addition & 1 deletion spec/truffle/tags/core/file/sticky_tags.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
fails:File.sticky? returns true if the file has sticky bit set
fails:File.sticky? returns true if the named file has the sticky bit, otherwise false
fails:File.sticky? cannot set sticky bit to a normal file
slow:File.sticky? returns true if the file has sticky bit set
1 change: 0 additions & 1 deletion spec/truffle/tags/core/file/symlink_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/file/truncate_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/truffle/tags/core/io/close_tags.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
fails:IO#close does not raise anything when self was already closed
fails:IO#close does nothing if already closed
slow:IO#close on an IO.popen stream clears #pid
slow:IO#close on an IO.popen stream sets $?
slow:IO#close on an IO.popen stream waits for the child to exit
1 change: 0 additions & 1 deletion spec/truffle/tags/core/io/foreach_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
fails:IO.foreach when the filename starts with | gets data from the standard out of the subprocess
fails:IO.foreach when the filename starts with | gets data from a fork when passed -
fails:IO.foreach sets $_ to nil
fails:IO.foreach when passed name, object when the object is a Fixnum uses the object as a limit if it is a Fixnum
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/io/output_tags.txt

This file was deleted.

4 changes: 2 additions & 2 deletions spec/truffle/tags/core/io/pid_tags.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
fails:IO#pid returns the ID of a process associated with stream
fails:IO#pid raises an IOError on closed stream
slow:IO#pid returns the ID of a process associated with stream
slow:IO#pid raises an IOError on closed stream
14 changes: 0 additions & 14 deletions spec/truffle/tags/core/io/popen_tags.txt
Original file line number Diff line number Diff line change
@@ -1,18 +1,4 @@
fails:IO.popen returns an open IO
fails:IO.popen reads a read-only pipe
fails:IO.popen raises IOError when writing a read-only pipe
fails:IO.popen writes to a write-only pipe
fails:IO.popen raises IOError when reading a write-only pipe
fails:IO.popen reads and writes a read/write pipe
fails:IO.popen waits for the child to finish
fails:IO.popen does not throw an exception if child exited and has been waited for
fails:IO.popen returns an instance of a subclass when called on a subclass
fails:IO.popen coerces mode argument with #to_str
fails:IO.popen starts returns a forked process if the command is -
fails:IO.popen has the given external encoding
fails:IO.popen has the given internal encoding
fails:IO.popen sets the internal encoding to nil if it's the same as the external encoding
fails:IO.popen with a block yields an open IO to the block
fails:IO.popen with a block yields an instance of a subclass when called on a subclass
fails:IO.popen with a block closes the IO after yielding
fails:IO.popen with a block allows the IO to be closed inside the block
1 change: 0 additions & 1 deletion spec/truffle/tags/core/io/puts_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
fails:IO#puts writes just a newline when given just a newline
fails:IO#puts calls :to_ary before writing non-string objects, regardless of it being implemented in the receiver
fails:IO#puts calls :to_ary before writing non-string objects
fails:IO#puts returns general object info if :to_s does not return a string
4 changes: 0 additions & 4 deletions spec/truffle/tags/core/io/read_nonblock_tags.txt

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/core/io/read_tags.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
fails:IO.read from a pipe runs the rest as a subprocess and returns the standard output
fails:IO.read from a pipe opens a pipe to a fork if the rest is -
fails:IO.read from a pipe reads only the specified number of bytes requested
fails:IO.read from a pipe raises Errno::ESPIPE if passed an offset
fails(hangs):IO#read raises IOError when stream is closed by another thread
fails(windows):IO#read on Windows normalizes line endings in text mode
fails(windows):IO#read on Windows does not normalize line endings in binary mode
1 change: 0 additions & 1 deletion spec/truffle/tags/core/io/readlines_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
fails:IO#readlines when passed a string that starts with a | gets data from the standard out of the subprocess
fails:IO#readlines when passed a string that starts with a | gets data from a fork when passed -
fails:IO.readlines when passed name, object when the object is a Fixnum uses the object as a limit if it is a Fixnum
fails:IO.readlines when passed name, object when the object is a String accepts non-ASCII data as separator
3 changes: 0 additions & 3 deletions spec/truffle/tags/core/io/select_tags.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
fails:IO.select blocks for duration of timeout if there are no objects ready for I/O
fails:IO.select returns immediately all objects that are ready for I/O when timeout is 0
fails:IO.select returns nil after timeout if there are no objects ready for I/O
fails:IO.select returns supplied objects when they are ready for I/O
fails:IO.select leaves out IO objects for which there is no I/O ready
fails:IO.select returns supplied objects correctly even when monitoring the same object in different arrays
fails:IO.select invokes to_io on supplied objects that are not IO and returns the supplied objects
fails:IO.select when passed nil for timeout sleeps forever
3 changes: 0 additions & 3 deletions spec/truffle/tags/core/io/stat_tags.txt

This file was deleted.

5 changes: 0 additions & 5 deletions spec/truffle/tags/core/io/sysread_tags.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1 @@
fails:IO#sysread on a file reads the specified number of bytes from the file
fails:IO#sysread on a file reads the specified number of bytes from the file to the buffer
fails:IO#sysread on a file coerces the second argument to string and uses it as a buffer
fails:IO#sysread on a file advances the position of the file by the specified number of bytes
fails:IO#sysread on a file reads normally even when called immediately after a buffered IO#read
fails:IO#sysread on a file reads updated content after the flushed buffered IO#write
1 change: 0 additions & 1 deletion spec/truffle/tags/core/io/sysseek_tags.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
fails:IO#sysseek does not accept Bignums that don't fit in a C long
fails:IO#sysseek moves the read position relative to the end with SEEK_END
3 changes: 0 additions & 3 deletions spec/truffle/tags/core/io/syswrite_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
fails:IO#syswrite on a file writes all of the string's bytes but does not buffer them
fails:IO#syswrite on a file warns if called immediately after a buffered IO#write
fails:IO#syswrite on a file does not warn if called after IO#write with intervening IO#sysread
fails:IO#syswrite on a file writes to the actual file position when called after buffered IO#read
1 change: 0 additions & 1 deletion spec/truffle/tags/core/io/tell_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/io/ungetbyte_tags.txt

This file was deleted.

2 changes: 1 addition & 1 deletion spec/truffle/tags/core/io/write_tags.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
fails(windows):IO#write on Windows normalizes line endings in text mode
fails(windows):IO#write on Windows does not normalize line endings in binary mode
fails:IO.write on a FIFO writes correctly
slow:IO.write on a FIFO writes correctly
12 changes: 0 additions & 12 deletions spec/truffle/tags/core/kernel/Float_tags.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,3 @@
fails:Kernel.Float raises an ArgumentError for a String of numbers followed by word characters
fails:Kernel.Float returns a value for a String with an embedded _
fails:Kernel.Float raises an ArgumentError for a String with an embedded \0
fails:Kernel.Float raises an ArgumentError for a String with a trailing \0
fails:Kernel.Float allows embedded _ in a number on either side of the e
fails:Kernel.Float allows embedded _ in a number on either side of the E
fails:Kernel#Float raises an ArgumentError for a String of numbers followed by word characters
fails:Kernel#Float returns a value for a String with an embedded _
fails:Kernel#Float raises an ArgumentError for a String with an embedded \0
fails:Kernel#Float raises an ArgumentError for a String with a trailing \0
fails:Kernel#Float allows embedded _ in a number on either side of the e
fails:Kernel#Float allows embedded _ in a number on either side of the E
fails:Kernel.Float for hexadecimal literals with binary exponent allows embedded _ in a number on either side of the p
fails:Kernel.Float for hexadecimal literals with binary exponent allows embedded _ in a number on either side of the P
fails:Kernel#Float for hexadecimal literals with binary exponent allows embedded _ in a number on either side of the p
1 change: 1 addition & 0 deletions spec/truffle/tags/core/kernel/backtick_tags.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
fails:Kernel#` produces a String in the default external encoding
fails:Kernel#` sets $? to the exit status of the executed sub-process
fails:Kernel#` raises an Errno::ENOENT if the command is not executable
slow:Kernel#` lets the standard error stream pass through to the inherited stderr
13 changes: 13 additions & 0 deletions spec/truffle/tags/core/kernel/chomp_tags.txt
Original file line number Diff line number Diff line change
@@ -11,3 +11,16 @@ slow:Kernel#chomp removes the value of $/ from the end of $_
slow:Kernel#chomp is a private method
slow:Kernel.chomp removes the final carriage return, newline from a multi-byte $_
slow:Kernel#chomp removes the final carriage return, newline from a multi-byte $_
fails:Kernel.chomp removes the final newline of $_
fails:Kernel.chomp removes the final carriage return of $_
fails:Kernel.chomp removes the final carriage return, newline of $_
fails:Kernel.chomp removes only the final newline of $_
fails:Kernel.chomp removes the value of $/ from the end of $_
fails:Kernel#chomp removes the final newline of $_
fails:Kernel#chomp removes the final carriage return of $_
fails:Kernel#chomp removes the final carriage return, newline of $_
fails:Kernel#chomp removes only the final newline of $_
fails:Kernel#chomp removes the value of $/ from the end of $_
fails:Kernel#chomp is a private method
fails:Kernel.chomp removes the final carriage return, newline from a multi-byte $_
fails:Kernel#chomp removes the final carriage return, newline from a multi-byte $_
3 changes: 0 additions & 3 deletions spec/truffle/tags/core/kernel/instance_of_tags.txt

This file was deleted.

4 changes: 0 additions & 4 deletions spec/truffle/tags/core/kernel/public_send_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/kernel/send_tags.txt

This file was deleted.

1 change: 1 addition & 0 deletions spec/truffle/tags/core/kernel/spawn_tags.txt
Original file line number Diff line number Diff line change
@@ -120,3 +120,4 @@ slow:Kernel.spawn uses the current umask by default
slow:Kernel.spawn when passed close_others: false closes file descriptors >= 3 in the child process because they are set close_on_exec by default
slow:Kernel.spawn when passed close_others: false does not close file descriptors >= 3 in the child process if fds are set close_on_exec=false
slow:Kernel#spawn with Integer option keys maps the key to a file descriptor in the child that inherits the file descriptor from the parent specified by the value
fails:Kernel#spawn does not unset environment variables included in the environment hash
1 change: 0 additions & 1 deletion spec/truffle/tags/core/kernel/throw_tags.txt

This file was deleted.

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

This file was deleted.

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

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/numeric/div_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/numeric/divmod_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/numeric/initialize_copy_tags.txt

This file was deleted.

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/proc/yield_tags.txt

This file was deleted.

4 changes: 0 additions & 4 deletions spec/truffle/tags/core/process/exec_tags.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
fails:Process.exec raises Errno::ENOENT for an empty string
fails:Process.exec raises Errno::ENOENT for a command which does not exist
fails:Process.exec raises an ArgumentError if the command includes a null byte
fails:Process.exec raises Errno::EACCES when the file does not have execute permissions
fails:Process.exec raises Errno::EACCES when passed a directory
fails:Process.exec runs the specified command, replacing current process
fails:Process.exec sets the current directory when given the :chdir option
fails:Process.exec flushes STDERR upon exit when it's not set to sync
fails:Process.exec with a single argument subjects the specified command to shell expansion
fails:Process.exec with a single argument creates an argument array with shell parsing semantics for whitespace
fails:Process.exec (environment variables) sets environment variables in the child environment
@@ -36,6 +34,4 @@ slow:Process.exec with a command array uses the first element as the command nam
slow:Process.exec with a command array coerces the argument using to_ary
slow:Process.exec with a command array raises an ArgumentError if the Array does not have exactly two elements
slow:Process.exec with an options Hash with Integer option keys maps the key to a file descriptor in the child that inherits the file descriptor from the parent specified by the value
fails:Process.exec flushes STDOUT upon exit when it's not set to sync
fails:Process.exec with multiple arguments does not subject the arguments to shell expansion

2 changes: 1 addition & 1 deletion spec/truffle/tags/core/process/groups_tags.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
fails:Process.groups gets an Array of the gids of groups in the supplemental group access list
fails:Process.groups sets the list of gids of groups in the supplemental group access list
fails:Process.groups gets an Array of the gids of groups in the supplemental group access list
1 change: 1 addition & 0 deletions spec/truffle/tags/core/process/kill_tags.txt
Original file line number Diff line number Diff line change
@@ -11,3 +11,4 @@ slow:Process.kill signals the process group if the PID is zero
slow:Process.kill signals the process group if the signal number is negative
slow:Process.kill signals the process group if the short signal name starts with a minus sign
slow:Process.kill signals the process group if the full signal name starts with a minus sign
fails(flakey):Process.kill signals the process group if the short signal name starts with a minus sign
1 change: 0 additions & 1 deletion spec/truffle/tags/core/process/setpgrp_tags.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
fails:Process.setpgrp and Process.getpgrp sets and gets the process group ID of the calling process
fails:Process.setpgrp and Process.getpgrp Process.setpgrp returns zero
20 changes: 0 additions & 20 deletions spec/truffle/tags/core/process/spawn_tags.txt
Original file line number Diff line number Diff line change
@@ -1,28 +1,8 @@
fails:Process.spawn executes the given command
fails:Process.spawn returns the process ID of the new process as a Fixnum
fails:Process.spawn returns immediately
fails:Process.spawn sets environment variables in the child environment
fails:Process.spawn unsets environment variables whose value is nil
fails:Process.spawn calls #to_hash to convert the environment
fails:Process.spawn calls #to_str to convert the environment keys
fails:Process.spawn calls #to_str to convert the environment values
fails:Process.spawn raises an ArgumentError if an environment key includes an equals sign
fails:Process.spawn raises an ArgumentError if an environment key includes a null byte
fails:Process.spawn raises an ArgumentError if an environment value includes a null byte
fails:Process.spawn unsets other environment variables when given a true :unsetenv_others option
fails:Process.spawn unsets other environment variables when given a non-false :unsetenv_others option
fails:Process.spawn does not unset other environment variables when given a false :unsetenv_others option
fails:Process.spawn does not unset other environment variables when given a nil :unsetenv_others option
fails:Process.spawn does not unset environment variables included in the environment hash
fails:Process.spawn joins the current process group by default
fails:Process.spawn joins the current process if pgroup: false
fails:Process.spawn joins the current process if pgroup: nil
fails:Process.spawn joins a new process group if pgroup: true
fails:Process.spawn joins a new process group if pgroup: 0
fails:Process.spawn joins the specified process group if pgroup: pgid
fails:Process.spawn raises an ArgumentError if given a negative :pgroup option
fails:Process.spawn raises a TypeError if given a symbol as :pgroup option
fails:Process.spawn uses the current working directory as its working directory
fails:Process.spawn uses the current umask by default
fails:Process.spawn sets the umask if given the :umask option
fails:Process.spawn raises an ArgumentError if passed no command arguments
1 change: 0 additions & 1 deletion spec/truffle/tags/core/process/wait2_tags.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
fails:Process.wait2 returns the pid and status of child process
fails:Process.wait2 raises a StandardError if no child processes exist
1 change: 0 additions & 1 deletion spec/truffle/tags/core/process/wait_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
fails:Process.wait raises an Errno::ECHILD if there are no child processes
fails:Process.wait returns its childs pid
fails:Process.wait sets $? to a Process::Status
fails:Process.wait waits for any child process if no pid is given
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/process/waitall_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
fails:Process.waitall returns an empty array when there are no children
fails:Process.waitall takes no arguments
fails:Process.waitall waits for all children
fails:Process.waitall returns an array of pid/status pairs
1 change: 0 additions & 1 deletion spec/truffle/tags/core/process/waitpid_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/range/eql_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/truffle/tags/core/string/modulo_tags.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
fails:String#% raises an ArgumentError for unused arguments when $DEBUG is true
fails:String#% supports float formats using %g
fails:String#% supports float formats using %G
fails:String#% raises an ArgumentError for huge precisions for %s
fails:String#% behaves as if calling Kernel#Float for %e arguments, when the passed argument does not respond to #to_ary
fails:String#% behaves as if calling Kernel#Float for %e arguments, when the passed argument is hexadecimal string
6 changes: 0 additions & 6 deletions spec/truffle/tags/core/thread/name_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/truffle/tags/core/threadgroup/add_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/truffle/tags/core/threadgroup/default_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/threadgroup/enclose_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/truffle/tags/core/threadgroup/enclosed_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/time/strftime_tags.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
fails:Time#strftime requires an argument
fails:Time#strftime rounds an offset to the nearest second when formatting with %z
fails:Time#strftime with %N formats the picoseconds of the second with %12N
1 change: 1 addition & 0 deletions spec/truffle/tags/language/predefined/data_tags.txt
Original file line number Diff line number Diff line change
@@ -5,3 +5,4 @@ slow:The DATA constant does not change when an included files also has a __END__
slow:The DATA constant is included in an otherwise empty file
slow:The DATA constant succeeds in locking the file DATA came from
slow:The DATA constant rewinds to the head of the main script
fails(travis):The DATA constant exists when the main script contains __END__
1 change: 0 additions & 1 deletion spec/truffle/tags/library/set/initialize_copy_tags.txt

This file was deleted.

This file was deleted.

7 changes: 6 additions & 1 deletion spec/truffle/truffle.mspec
Original file line number Diff line number Diff line change
@@ -36,7 +36,12 @@ class MSpecScript
]

set :core, [
"spec/ruby/core"
"spec/ruby/core",

# Troublesome - they do work, but sometimes fail, sometimes timeout
"^spec/ruby/core/io/io_spec.rb",
"^spec/ruby/core/io/popen_spec.rb",
"^spec/ruby/core/io/pipe_spec.rb"
]

set :library, [
1 change: 1 addition & 0 deletions test/mri/excludes_truffle/TestDir_M17N.rb
Original file line number Diff line number Diff line change
@@ -16,3 +16,4 @@
exclude :"test_glob_warning_match_all", "needs investigation"
exclude :"test_glob_warning_match_dir", "needs investigation"
exclude :test_glob_warning_opendir, "needs investigation"
exclude :test_pwd, "needs investigation"
2 changes: 2 additions & 0 deletions test/mri/excludes_truffle/TestOpen3.rb
Original file line number Diff line number Diff line change
@@ -22,3 +22,5 @@
exclude :test_capture2e_stdin_data, "needs investigation"
exclude :test_capture3_flip, "needs investigation"
exclude :"test_env", "needs investigation"
exclude :test_numeric_file_descriptor2, "needs investigation"
exclude :test_numeric_file_descriptor3, "needs investigation"
1 change: 1 addition & 0 deletions test/mri/excludes_truffle/TestSignal.rb
Original file line number Diff line number Diff line change
@@ -14,3 +14,4 @@
exclude :test_trap_uncatchable_KILL, "needs investigation"
exclude :test_trap_uncatchable_STOP, "needs investigation"
exclude :test_sigexit, "needs investigation"
exclude :test_signame_delivered, "needs investigation"
5 changes: 0 additions & 5 deletions test/mri/excludes_truffle/TestSprintf.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
exclude :test_binary, "needs investigation"
exclude :test_char, "needs investigation"
exclude :test_float, "needs investigation"
exclude :test_float2, "needs investigation"
exclude :test_float_hex, "needs investigation"
exclude :test_hash, "needs investigation"
exclude :test_inf, "needs investigation"
exclude :test_integer, "needs investigation"
exclude :test_invalid, "needs investigation"
@@ -12,9 +9,7 @@
exclude :test_named_untyped, "needs investigation"
exclude :test_named_untyped_enc, "needs investigation"
exclude :test_nan, "needs investigation"
exclude :test_positional, "needs investigation"
exclude :test_rational, "needs investigation"
exclude :test_star, "needs investigation"
exclude :test_string, "needs investigation"
exclude :test_negative_hex , "needs investigation"
exclude :"test_named_default", "needs investigation"
8 changes: 7 additions & 1 deletion test/truffle/ecosystem-travis-install.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
#!/usr/bin/env bash

gem install bundler
set -e
set -x

unset GEM_HOME GEM_PATH

bin/jruby bin/gem install bundler

git clone \
--branch master \
https://github.com/jruby/jruby-truffle-gem-test-pack.git \
1 change: 1 addition & 0 deletions test/truffle/ecosystem/batch.yaml
Original file line number Diff line number Diff line change
@@ -3,5 +3,6 @@
- activesupport
- activemodel
- algebrick
- railties

# - [gem_name, --option] # is alternative format
1 change: 1 addition & 0 deletions test/truffle/gems/install-gems.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env bash

set -e
set -x

bin/jruby bin/gem install execjs -v 2.6.0
bin/jruby bin/gem install rack -v 1.6.1
4 changes: 2 additions & 2 deletions test/truffle/integration/coverage/test.rb
Original file line number Diff line number Diff line change
@@ -13,8 +13,8 @@
require_relative 'subject.rb'

result = Coverage.result
key = result.keys.select { |k| k.end_with?('subject.rb') }.first
key = result.keys.find { |k| k.end_with?('subject.rb') }
data = result[key]
expected = [nil, nil, nil, nil, nil, nil, nil, nil, 1, 1, nil, 1, 10, nil, nil, 1, nil, 1, 1, nil, nil, 1, 2, nil, nil, 1, 1, nil, 1]

raise 'coverage data not as expected' unless data == expected
raise "coverage data not as expected: #{data}" unless data == expected
70 changes: 40 additions & 30 deletions tool/jt.rb
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@
require 'yaml'
require 'open3'

GRAALVM_VERSION = '0.15'
GRAALVM_VERSION = '0.16'

JRUBY_DIR = File.expand_path('../..', __FILE__)
M2_REPO = File.expand_path('~/.m2/repository')
@@ -91,12 +91,7 @@ def self.find_graal_javacmd_and_options
options = []
elsif graal_home
graal_home = File.expand_path(graal_home)
if ENV['JVMCI_JAVA_HOME']
mx_options = "--java-home #{ENV['JVMCI_JAVA_HOME']}"
else
mx_options = ''
end
command_line = `mx -v #{mx_options} -p #{graal_home} vm -version`.lines.to_a.last
command_line = `mx -v -p #{graal_home} vm -version`.lines.to_a.last
vm_args = command_line.split
vm_args.pop # Drop "-version"
javacmd = vm_args.shift
@@ -152,12 +147,12 @@ def self.find_ruby
end

def self.find_jruby
if mx?
if ENV['RUBY_BIN']
ENV['RUBY_BIN']
elsif mx?
"#{JRUBY_DIR}/tool/jruby_mx"
elsif jruby_eclipse?
"#{JRUBY_DIR}/tool/jruby_eclipse"
elsif ENV['RUBY_BIN']
ENV['RUBY_BIN']
else
"#{JRUBY_DIR}/bin/jruby"
end
@@ -166,10 +161,15 @@ def self.find_jruby
def self.find_jruby_bin_dir
# Make sure bin/ruby points to the right launcher
ruby_symlink = "#{JRUBY_DIR}/bin/ruby"
FileUtils.rm_f ruby_symlink
File.symlink Utilities.find_jruby, ruby_symlink
jruby_bin = Utilities.find_jruby
if File.symlink?(ruby_symlink) && File.expand_path(File.readlink(ruby_symlink), File.dirname(ruby_symlink)) != jruby_bin
FileUtils.rm_f ruby_symlink
File.symlink jruby_bin, ruby_symlink
end

if jruby_eclipse? or mx?
if ENV['RUBY_BIN']
File.dirname(ENV['RUBY_BIN'])
elsif jruby_eclipse? or mx?
JRUBY_DIR + "/bin"
else
File.dirname(find_jruby)
@@ -368,17 +368,19 @@ def mvn(*args)

def maven_options(*options)
maven_options = []
build_pack = options.delete('--build-pack')
offline = options.delete('--offline')
if offline
if build_pack || offline
maven_options.push "-Dmaven.repo.local=#{Utilities.find_repo('jruby-build-pack')}/maven"
end
if offline
maven_options.push '--offline'
end
return [maven_options, options]
end

def mx(dir, *args)
command = ['mx', '-p', dir]
command.push *['--java-home', ENV['JVMCI_JAVA_HOME']] if ENV['JVMCI_JAVA_HOME']
command.push *args
sh *command
end
@@ -445,12 +447,13 @@ def help
jt rebuild [options] clean and build
truffle build only the Truffle part, assumes the rest is up-to-date
cexts [--no-openssl] build the cext backend (set SULONG_HOME and maybe USE_SYSTEM_CLANG)
--build-pack use the build pack
--offline use the build pack to build offline
jt clean clean
jt irb irb
jt rebuild clean and build
jt run [options] args... run JRuby with -X+T and args
--graal use Graal (set either GRAALVM_BIN or GRAAL_HOME and maybe JVMCI_JAVA_HOME)
--graal use Graal (set either GRAALVM_BIN or GRAAL_HOME)
--js add Graal.js to the classpath (set GRAAL_JS_JAR)
--asm show assembly (implies --graal)
--server run an instrumentation server on port 8080
@@ -492,7 +495,8 @@ def help
jt metrics time ... how long does it take to run a command, broken down into different phases
jt tarball build the and test the distribution tarball
jt benchmark [options] args... run benchmark-interface (implies --graal)
--no-graal don\'t imply --graal
--no-graal don't imply --graal
JT_BENCHMARK_RUBY=ruby benchmark some other Ruby, like MRI
note that to run most MRI benchmarks, you should translate them first with normal Ruby and cache the result, such as
benchmark bench/mri/bm_vm1_not.rb --cache
jt benchmark bench/mri/bm_vm1_not.rb --use-cache
@@ -504,9 +508,7 @@ def help

RUBY_BIN The JRuby+Truffle executable to use (normally just bin/jruby)
GRAALVM_BIN GraalVM executable (java command) to use
GRAAL_HOME Directory where there is a built checkout of the Graal compiler
(make sure mx is on your path and maybe set JVMCI_JAVA_HOME)
JVMCI_JAVA_HOME The Java with JVMCI to use with GRAAL_HOME
GRAAL_HOME Directory where there is a built checkout of the Graal compiler (make sure mx is on your path)
GRAALVM_RELEASE_BIN Default GraalVM executable when using a released version of Truffle (such as on master)
GRAAL_HOME_TRUFFLE_HEAD Default Graal directory when using a snapshot version of Truffle (such as on truffle-head)
SULONG_HOME The Sulong source repository, if you want to run cextc
@@ -539,10 +541,7 @@ def build(*options)
no_openssl = options.delete('--no-openssl')
cextc "#{JRUBY_DIR}/truffle/src/main/c/cext"
unless no_openssl
cextc "#{JRUBY_DIR}/truffle/src/main/c/openssl",
'-DRUBY_EXTCONF_H="extconf.h"',
'-DJT_INT_VALUE=true',
'-Werror=implicit-function-declaration'
cextc "#{JRUBY_DIR}/truffle/src/main/c/openssl"
end
when nil
mvn env, *maven_options, 'package'
@@ -861,7 +860,7 @@ def test_cexts(*args)
['oily_png', ['chunky_png-1.3.6', 'oily_png-1.2.0'], ['oily_png']],
['psd_native', ['chunky_png-1.3.6', 'oily_png-1.2.0', 'bindata-2.3.1', 'hashie-3.4.4', 'psd-enginedata-1.1.1', 'psd-2.1.2', 'psd_native-1.1.3'], ['oily_png', 'psd_native']],
['nokogiri', [], ['nokogiri']],
['ruby-argon2', [], [], "#{ENV['GEM_HOME']}/bundler/gems/ruby-argon2-5a527075e88b"]
['ruby-argon2', [], [], "#{ENV['GEM_HOME']}/bundler/gems/ruby-argon2-bd3fb1e056cf"]
].each do |gem_name, dependencies, libs, gem_root|
next if gem_name == 'nokogiri' # nokogiri totally excluded
next if gem_name == 'nokogiri' && no_libxml
@@ -1215,15 +1214,26 @@ def benchmark(*args)
a
end
end


benchmark_ruby = ENV['JT_BENCHMARK_RUBY']

run_args = []
run_args.push '--graal' unless args.delete('--no-graal') || args.include?('list')
run_args.push '-J-G:+TruffleCompilationExceptionsAreFatal'

unless benchmark_ruby
run_args.push '--graal' unless args.delete('--no-graal') || args.include?('list')
run_args.push '-J-G:+TruffleCompilationExceptionsAreFatal'
end

run_args.push "-I#{Utilities.find_gem('deep-bench')}/lib" rescue nil
run_args.push "-I#{Utilities.find_gem('benchmark-ips')}/lib" rescue nil
run_args.push "#{Utilities.find_gem('benchmark-interface')}/bin/benchmark"
run_args.push *args
run *run_args

if benchmark_ruby
sh benchmark_ruby, *run_args
else
run *run_args
end
end

def where(*args)
@@ -1272,7 +1282,7 @@ def main(args)
send(args.shift)
when "build"
command = [args.shift]
while ['truffle', 'cexts', '--offline', '--no-openssl'].include?(args.first)
while ['truffle', 'cexts', '--offline', '--build-pack', '--no-openssl'].include?(args.first)
command << args.shift
end
send(*command)
5 changes: 1 addition & 4 deletions truffle/pom.rb
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@

properties( 'polyglot.dump.pom' => 'pom.xml',
'polyglot.dump.readonly' => true,
'truffle.version' => '0.16',
'truffle.version' => '0.17',
'jruby.basedir' => '${basedir}/..',
'maven.test.skip' => 'true' )

@@ -18,9 +18,6 @@

jar 'org.jruby:jruby-core', '${project.version}', :scope => 'provided'

repository( :url => 'http://lafo.ssw.uni-linz.ac.at/nexus/content/repositories/snapshots/',
:id => 'truffle' )

truffle_version = '${truffle.version}'
jar 'com.oracle.truffle:truffle-api:' + truffle_version
jar 'com.oracle.truffle:truffle-debug:' + truffle_version
8 changes: 1 addition & 7 deletions truffle/pom.xml
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ DO NOT MODIFIY - GENERATED CODE
<jruby.basedir>${basedir}/..</jruby.basedir>
<polyglot.dump.readonly>true</polyglot.dump.readonly>
<polyglot.dump.pom>pom.xml</polyglot.dump.pom>
<truffle.version>0.16</truffle.version>
<truffle.version>0.17</truffle.version>
</properties>
<dependencies>
<dependency>
@@ -68,12 +68,6 @@ DO NOT MODIFIY - GENERATED CODE
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>truffle</id>
<url>http://lafo.ssw.uni-linz.ac.at/nexus/content/repositories/snapshots/</url>
</repository>
</repositories>
<build>
<defaultGoal>package</defaultGoal>
<resources>
110 changes: 58 additions & 52 deletions truffle/src/main/c/cext/ruby.c
Original file line number Diff line number Diff line change
@@ -19,27 +19,28 @@
#include <truffle.h>

#include <ruby.h>

// Helpers

VALUE rb_f_notimplement(int args_count, const VALUE *args, VALUE object) {
fprintf(stderr, "rb_f_notimplement\n");
rb_jt_error("rb_f_notimplement");
abort();
}

// Memory

void *rb_alloc_tmp_buffer(volatile VALUE *buffer_pointer, long length) {
fprintf(stderr, "rb_alloc_tmp_buffer not implemented\n");
rb_jt_error("rb_alloc_tmp_buffer not implemented");
abort();
}

void *rb_alloc_tmp_buffer2(volatile VALUE *buffer_pointer, long count, size_t size) {
fprintf(stderr, "rb_alloc_tmp_buffer2 not implemented\n");
rb_jt_error("rb_alloc_tmp_buffer2 not implemented");
abort();
}

void rb_free_tmp_buffer(volatile VALUE *buffer_pointer) {
fprintf(stderr, "rb_free_tmp_buffer not implemented\n");
rb_jt_error("rb_free_tmp_buffer not implemented");
abort();
}

@@ -66,12 +67,12 @@ VALUE rb_obj_is_kind_of(VALUE object, VALUE ruby_class) {
}

void rb_check_frozen(VALUE object) {
fprintf(stderr, "rb_check_frozen not implemented\n");
rb_jt_error("rb_check_frozen not implemented");
abort();
}

void rb_check_safe_obj(VALUE object) {
fprintf(stderr, "rb_check_safe_obj not implemented\n");
rb_jt_error("rb_check_safe_obj not implemented");
abort();
}

@@ -269,8 +270,7 @@ int RTEST(VALUE value) {
// Kernel

VALUE rb_require(const char *feature) {
fprintf(stderr, "rb_require not implemented\n");
abort();
return (VALUE) truffle_invoke(RUBY_CEXT, "rb_require", rb_str_new_cstr(feature));
}

// Object
@@ -306,22 +306,22 @@ VALUE rb_Integer(VALUE value) {
}

int rb_integer_pack(VALUE value, void *words, size_t numwords, size_t wordsize, size_t nails, int flags) {
fprintf(stderr, "rb_integer_pack not implemented\n");
rb_jt_error("rb_integer_pack not implemented");
abort();
}

VALUE rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags) {
fprintf(stderr, "rb_integer_unpack not implemented\n");
rb_jt_error("rb_integer_unpack not implemented");
abort();
}

size_t rb_absint_size(VALUE value, int *nlz_bits_ret) {
fprintf(stderr, "rb_absint_size not implemented\n");
rb_jt_error("rb_absint_size not implemented");
abort();
}

VALUE rb_cstr_to_inum(const char* string, int base, int raise) {
fprintf(stderr, "rb_cstr_to_inum not implemented\n");
rb_jt_error("rb_cstr_to_inum not implemented");
abort();
}

@@ -350,7 +350,9 @@ int rb_str_len(VALUE string) {
}

VALUE rb_str_new(const char *string, long length) {
if (truffle_is_truffle_object((VALUE) string)) {
if (string == NULL) {
return (VALUE) truffle_invoke(RUBY_CEXT, "rb_str_new_nul", length);
} else if (truffle_is_truffle_object((VALUE) string)) {
return (VALUE) truffle_invoke(RUBY_CEXT, "rb_str_new", string, length);
} else {
return (VALUE) truffle_invoke(RUBY_CEXT, "rb_str_new_cstr", truffle_read_n_string(string, length));
@@ -400,7 +402,7 @@ char *rb_string_value_ptr(volatile VALUE* value_pointer) {
}

char *rb_string_value_cstr(volatile VALUE* value_pointer) {
fprintf(stderr, "rb_string_value_cstr not implemented\n");
rb_jt_error("rb_string_value_cstr not implemented");
abort();
}

@@ -417,17 +419,17 @@ VALUE rb_sprintf(const char *format, ...) {
}

VALUE rb_vsprintf(const char *format, va_list args) {
fprintf(stderr, "rb_vsprintf not implemented\n");
rb_jt_error("rb_vsprintf not implemented");
abort();
}

VALUE rb_str_append(VALUE string, VALUE to_append) {
fprintf(stderr, "rb_str_append not implemented\n");
rb_jt_error("rb_str_append not implemented");
abort();
}

void rb_str_set_len(VALUE string, long length) {
fprintf(stderr, "rb_str_set_len not implemented\n");
rb_jt_error("rb_str_set_len not implemented");
abort();
}

@@ -440,7 +442,7 @@ VALUE rb_String(VALUE value) {
}

VALUE rb_str_resize(VALUE string, long length) {
fprintf(stderr, "rb_str_resize not implemented\n");
rb_jt_error("rb_str_resize not implemented");
abort();
}

@@ -531,12 +533,12 @@ VALUE rb_ary_dup(VALUE array) {
}

VALUE rb_ary_each(VALUE array) {
fprintf(stderr, "rb_ary_each not implemented\n");
rb_jt_error("rb_ary_each not implemented");
abort();
}

VALUE rb_check_array_type(VALUE array) {
fprintf(stderr, "rb_check_array_type not implemented\n");
rb_jt_error("rb_check_array_type not implemented");
abort();
}

@@ -551,21 +553,20 @@ VALUE rb_hash_aref(VALUE hash, VALUE key) {
}

VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE value) {
truffle_write(hash, key, value);
return (VALUE) truffle_invoke((void *)hash, "[]=", key, value);
return value;
}

VALUE rb_hash_lookup(VALUE hash, VALUE key) {
return truffle_read(hash, key);
return (VALUE) truffle_invoke((void *)hash, "[]", key);
}

VALUE rb_hash_lookup2(VALUE hash, VALUE key, VALUE default_value) {
return (VALUE) truffle_invoke((void *)hash, "fetch", key, default_value);
}

VALUE rb_hash_set_ifnone(VALUE hash, VALUE if_none) {
fprintf(stderr, "rb_hash_set_ifnone not implemented\n");
abort();
return (VALUE) truffle_invoke(RUBY_CEXT, "rb_hash_set_ifnone", hash, if_none);
}

st_index_t rb_memhash(const void *data, long length) {
@@ -598,6 +599,10 @@ VALUE rb_obj_class(VALUE object) {
return rb_class_real(rb_class_of(object));
}

VALUE CLASS_OF(VALUE object) {
return (VALUE) truffle_invoke(RUBY_CEXT, "CLASS_OF", object);
}

VALUE rb_class_of(VALUE object) {
return (VALUE) truffle_invoke((void *)object, "class");
}
@@ -607,13 +612,12 @@ VALUE rb_obj_alloc(VALUE ruby_class) {
}

VALUE rb_class_path(VALUE ruby_class) {
fprintf(stderr, "rb_class_path not implemented\n");
rb_jt_error("rb_class_path not implemented");
abort();
}

VALUE rb_path2class(const char *string) {
fprintf(stderr, "rb_path2class not implemented\n");
abort();
return (VALUE) truffle_invoke(RUBY_CEXT, "rb_path2class", rb_str_new_cstr(string));
}

// Proc
@@ -653,27 +657,27 @@ int rb_respond_to(VALUE object, ID name) {
}

VALUE rb_funcallv(VALUE object, ID name, int args_count, const VALUE *args) {
fprintf(stderr, "rb_funcallv not implemented\n");
rb_jt_error("rb_funcallv not implemented");
abort();
}

VALUE rb_funcallv_public(VALUE object, ID name, int args_count, const VALUE *args) {
fprintf(stderr, "rb_funcallv_public not implemented\n");
rb_jt_error("rb_funcallv_public not implemented");
abort();
}

VALUE rb_apply(VALUE object, ID name, VALUE args) {
fprintf(stderr, "rb_apply not implemented\n");
rb_jt_error("rb_apply not implemented");
abort();
}

VALUE rb_block_call(VALUE object, ID name, int args_count, const VALUE *args, rb_block_call_func_t block_call_func, VALUE data) {
fprintf(stderr, "rb_block_call not implemented\n");
rb_jt_error("rb_block_call not implemented");
abort();
}

VALUE rb_call_super(int args_count, const VALUE *args) {
fprintf(stderr, "rb_call_super not implemented\n");
rb_jt_error("rb_call_super not implemented");
abort();
}

@@ -682,7 +686,7 @@ int rb_block_given_p() {
}

VALUE rb_block_proc(void) {
fprintf(stderr, "rb_block_proc not implemented\n");
rb_jt_error("rb_block_proc not implemented");
abort();
}

@@ -764,7 +768,7 @@ void rb_exc_raise(VALUE exception) {
}

void rb_raise(VALUE exception, const char *format, ...) {
fprintf(stderr, "rb_raise not implemented\n");
rb_jt_error("rb_raise not implemented");
truffle_invoke(RUBY_CEXT, "rb_raise", format /*, where to get args? */);
abort();
}
@@ -776,25 +780,23 @@ VALUE rb_protect(VALUE (*function)(VALUE), VALUE data, int *status) {

void rb_jump_tag(int status) {
if (status) {
// TODO CS 23-Jul-16
fprintf(stderr, "rb_jump_tag not implemented\n");
rb_jt_error("rb_jump_tag not implemented");
abort();
}
}

void rb_set_errinfo(VALUE error) {
// TODO CS 23-Jul-16
fprintf(stderr, "rb_set_errinfo not implemented\n");
rb_jt_error("rb_set_errinfo not implemented");
abort();
}

void rb_syserr_fail(int errno, const char *message) {
fprintf(stderr, "rb_syserr_fail: %d %s\n", errno, message);
rb_jt_error(message);
abort();
}

void rb_sys_fail(const char *message) {
fprintf(stderr, "rb_sys_fail: %s\n", message);
rb_jt_error(message);
abort();
}

@@ -865,13 +867,11 @@ void rb_undef(VALUE module, ID name) {
}

void rb_attr(VALUE ruby_class, ID name, int read, int write, int ex) {
fprintf(stderr, "rb_attr not implemented\n");
abort();
truffle_invoke(RUBY_CEXT, "rb_attr", ruby_class, name, read, write, ex);
}

void rb_define_alloc_func(VALUE ruby_class, rb_alloc_func_t alloc_function) {
fprintf(stderr, "rb_define_alloc_func not implemented\n");
abort();
truffle_invoke(RUBY_CEXT, "rb_define_alloc_func", ruby_class, truffle_address_to_function(alloc_function));
}

// Rational
@@ -1024,12 +1024,12 @@ void rb_io_check_readable(rb_io_t *io) {
}

int rb_cloexec_dup(int oldfd) {
fprintf(stderr, "rb_cloexec_dup not implemented\n");
rb_jt_error("rb_cloexec_dup not implemented");
abort();
}

void rb_fd_fix_cloexec(int fd) {
fprintf(stderr, "rb_fd_fix_cloexec not implemented\n");
rb_jt_error("rb_fd_fix_cloexec not implemented");
abort();
}

@@ -1038,29 +1038,29 @@ int rb_jt_io_handle(VALUE io) {
}

int rb_io_wait_readable(int fd) {
fprintf(stderr, "rb_io_wait_readable not implemented\n");
rb_jt_error("rb_io_wait_readable not implemented");
abort();
}

int rb_io_wait_writable(int fd) {
fprintf(stderr, "rb_io_wait_writable not implemented\n");
rb_jt_error("rb_io_wait_writable not implemented");
abort();
}

void rb_thread_wait_fd(int fd) {
fprintf(stderr, "rb_thread_wait_fd not implemented\n");
rb_jt_error("rb_thread_wait_fd not implemented");
abort();
}

NORETURN(void rb_eof_error(void)) {
fprintf(stderr, "rb_eof_error not implemented\n");
rb_jt_error("rb_eof_error not implemented");
abort();
}

// Data

struct RData *rb_jt_wrap_rdata(VALUE value) {
fprintf(stderr, "RDATA not implemented\n");
rb_jt_error("RDATA not implemented");
abort();
}

@@ -1082,7 +1082,7 @@ VALUE rb_data_typed_object_make(VALUE ruby_class, const rb_data_type_t *type, vo
}

void *rb_check_typeddata(VALUE value, const rb_data_type_t *data_type) {
fprintf(stderr, "rb_check_typeddata not implemented\n");
rb_jt_error("rb_check_typeddata not implemented");
abort();
}

@@ -1101,3 +1101,9 @@ VALUE *rb_ruby_debug_ptr(void) {
rb_jt_ruby_debug_ptr = truffle_invoke(RUBY_CEXT, "rb_ruby_debug_ptr");
return &rb_jt_ruby_debug_ptr;
}

// Non-standard

void rb_jt_error(const char *message) {
truffle_invoke(RUBY_CEXT, "rb_jt_error", rb_str_new_cstr(message));
}
2 changes: 1 addition & 1 deletion truffle/src/main/c/openssl/.jruby-cext-build.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
src: ./*.c
cflags: -I$OPENSSL_INCLUDE
cflags: -I$OPENSSL_INCLUDE -DRUBY_EXTCONF_H="extconf.h" -DHAVE_OPENSSL_110_THREADING_API -Werror=implicit-function-declaration
libs: $OPENSSL_LIB
out: ../../../../../lib/ruby/truffle/openssl/openssl.su
64 changes: 33 additions & 31 deletions truffle/src/main/c/openssl/ossl_asn1.c
Original file line number Diff line number Diff line change
@@ -509,38 +509,40 @@ typedef struct {
VALUE *klass;
} ossl_asn1_info_t;

// TODO CS 06-09-16 Removed the address of the classes for now as it causes problems in Sulong

static const ossl_asn1_info_t ossl_asn1_info[] = {
{ "EOC", &cASN1EndOfContent, }, /* 0 */
{ "BOOLEAN", &cASN1Boolean, }, /* 1 */
{ "INTEGER", &cASN1Integer, }, /* 2 */
{ "BIT_STRING", &cASN1BitString, }, /* 3 */
{ "OCTET_STRING", &cASN1OctetString, }, /* 4 */
{ "NULL", &cASN1Null, }, /* 5 */
{ "OBJECT", &cASN1ObjectId, }, /* 6 */
{ "OBJECT_DESCRIPTOR", NULL, }, /* 7 */
{ "EXTERNAL", NULL, }, /* 8 */
{ "REAL", NULL, }, /* 9 */
{ "ENUMERATED", &cASN1Enumerated, }, /* 10 */
{ "EMBEDDED_PDV", NULL, }, /* 11 */
{ "UTF8STRING", &cASN1UTF8String, }, /* 12 */
{ "RELATIVE_OID", NULL, }, /* 13 */
{ "[UNIVERSAL 14]", NULL, }, /* 14 */
{ "[UNIVERSAL 15]", NULL, }, /* 15 */
{ "SEQUENCE", &cASN1Sequence, }, /* 16 */
{ "SET", &cASN1Set, }, /* 17 */
{ "NUMERICSTRING", &cASN1NumericString, }, /* 18 */
{ "PRINTABLESTRING", &cASN1PrintableString, }, /* 19 */
{ "T61STRING", &cASN1T61String, }, /* 20 */
{ "VIDEOTEXSTRING", &cASN1VideotexString, }, /* 21 */
{ "IA5STRING", &cASN1IA5String, }, /* 22 */
{ "UTCTIME", &cASN1UTCTime, }, /* 23 */
{ "GENERALIZEDTIME", &cASN1GeneralizedTime, }, /* 24 */
{ "GRAPHICSTRING", &cASN1GraphicString, }, /* 25 */
{ "ISO64STRING", &cASN1ISO64String, }, /* 26 */
{ "GENERALSTRING", &cASN1GeneralString, }, /* 27 */
{ "UNIVERSALSTRING", &cASN1UniversalString, }, /* 28 */
{ "CHARACTER_STRING", NULL, }, /* 29 */
{ "BMPSTRING", &cASN1BMPString, }, /* 30 */
{ "EOC", NULL /*&cASN1EndOfContent*/, }, /* 0 */
{ "BOOLEAN", NULL /*&cASN1Boolean*/, }, /* 1 */
{ "INTEGER", NULL /*&cASN1Integer*/, }, /* 2 */
{ "BIT_STRING", NULL /*&cASN1BitString*/, }, /* 3 */
{ "OCTET_STRING", NULL /*&cASN1OctetString*/, }, /* 4 */
{ "NULL", NULL /*&cASN1Null*/, }, /* 5 */
{ "OBJECT", NULL /*&cASN1ObjectId*/, }, /* 6 */
{ "OBJECT_DESCRIPTOR", NULL, }, /* 7 */
{ "EXTERNAL", NULL, }, /* 8 */
{ "REAL", NULL, }, /* 9 */
{ "ENUMERATED", NULL /*&cASN1Enumerated*/, }, /* 10 */
{ "EMBEDDED_PDV", NULL, }, /* 11 */
{ "UTF8STRING", NULL /*&cASN1UTF8String*/, }, /* 12 */
{ "RELATIVE_OID", NULL, }, /* 13 */
{ "[UNIVERSAL 14]", NULL, }, /* 14 */
{ "[UNIVERSAL 15]", NULL, }, /* 15 */
{ "SEQUENCE", NULL /*&cASN1Sequence*/, }, /* 16 */
{ "SET", NULL /*&cASN1Set*/, }, /* 17 */
{ "NUMERICSTRING", NULL /*&cASN1NumericString*/, }, /* 18 */
{ "PRINTABLESTRING", NULL /*&cASN1PrintableString*/, }, /* 19 */
{ "T61STRING", NULL /*&cASN1T61String*/, }, /* 20 */
{ "VIDEOTEXSTRING", NULL /*&cASN1VideotexString*/, }, /* 21 */
{ "IA5STRING", NULL /*&cASN1IA5String*/, }, /* 22 */
{ "UTCTIME", NULL /*&cASN1UTCTime*/, }, /* 23 */
{ "GENERALIZEDTIME", NULL /*&cASN1GeneralizedTime*/, }, /* 24 */
{ "GRAPHICSTRING", NULL /*&cASN1GraphicString*/, }, /* 25 */
{ "ISO64STRING", NULL /*&cASN1ISO64String*/, }, /* 26 */
{ "GENERALSTRING", NULL /*&cASN1GeneralString*/, }, /* 27 */
{ "UNIVERSALSTRING", NULL /*&cASN1UniversalString*/, }, /* 28 */
{ "CHARACTER_STRING", NULL, }, /* 29 */
{ "BMPSTRING", NULL /*&cASN1BMPString*/, }, /* 30 */
};

enum {ossl_asn1_info_size = (sizeof(ossl_asn1_info)/sizeof(ossl_asn1_info[0]))};
2 changes: 1 addition & 1 deletion truffle/src/main/c/openssl/ossl_ocsp.c
Original file line number Diff line number Diff line change
@@ -399,7 +399,7 @@ ossl_ocspreq_sign(int argc, VALUE *argv, VALUE self)
else
md = GetDigestPtr(digest);
if (NIL_P(certs))
flags |= OCSP_NOCERTS;
flg |= OCSP_NOCERTS;
else
x509s = ossl_x509_ary2sk(certs);

19 changes: 5 additions & 14 deletions truffle/src/main/java/org/jruby/truffle/JRubyTruffleImpl.java
Original file line number Diff line number Diff line change
@@ -11,8 +11,6 @@

import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.vm.PolyglotEngine;
import java.io.IOException;

import org.jruby.JRubyTruffleInterface;
import org.jruby.Ruby;
import org.jruby.truffle.interop.JRubyContextWrapper;
@@ -21,6 +19,8 @@
import org.jruby.truffle.platform.graal.Graal;
import org.jruby.util.cli.Options;

import java.io.IOException;

public class JRubyTruffleImpl implements JRubyTruffleInterface {

private final PolyglotEngine engine;
@@ -32,11 +32,7 @@ public JRubyTruffleImpl(Ruby runtime) {
engine = PolyglotEngine.newBuilder()
.globalSymbol(JRubyTruffleInterface.RUNTIME_SYMBOL, new JRubyContextWrapper(runtime))
.build();
try {
context = (RubyContext) engine.eval(loadSource("Truffle::Boot.context", "context")).get();
} catch (IOException e) {
throw new JavaException(e);
}
context = (RubyContext) engine.eval(loadSource("Truffle::Boot.context", "context")).get();
}

@Override
@@ -51,13 +47,8 @@ public Object execute(org.jruby.ast.RootNode rootNode) {

try {
return engine.eval(loadSource("Truffle::Boot.run_jruby_root", "run_jruby_root")).get();
} catch (IOException e) {
if (e.getCause() instanceof ExitException) {
final ExitException exit = (ExitException) e.getCause();
throw new org.jruby.exceptions.MainExitException(exit.getCode());
}

throw new JavaException(e);
} catch (ExitException e) {
throw new org.jruby.exceptions.MainExitException(e.getCode());
}
}

7 changes: 1 addition & 6 deletions truffle/src/main/java/org/jruby/truffle/RubyContext.java
Original file line number Diff line number Diff line change
@@ -16,7 +16,6 @@
import com.oracle.truffle.api.TruffleLanguage;
import com.oracle.truffle.api.instrumentation.Instrumenter;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.Source;
import org.jruby.Ruby;
import org.jruby.truffle.builtins.PrimitiveManager;
import org.jruby.truffle.core.CoreLibrary;
@@ -153,12 +152,8 @@ public RubyContext(Ruby jrubyRuntime, TruffleLanguage.Env env) {

// Load the nodes

org.jruby.Main.printTruffleTimeMetric("before-load-primitives");
coreLibrary.addPrimitives();
org.jruby.Main.printTruffleTimeMetric("after-load-primitives");

org.jruby.Main.printTruffleTimeMetric("before-load-nodes");
coreLibrary.addCoreMethods();
coreLibrary.addCoreMethods(primitiveManager);
org.jruby.Main.printTruffleTimeMetric("after-load-nodes");

// Load the reset of the core library
Original file line number Diff line number Diff line change
@@ -30,19 +30,22 @@
import org.jruby.truffle.language.RubyGuards;
import org.jruby.truffle.language.RubyNode;
import org.jruby.truffle.language.RubyRootNode;
import org.jruby.truffle.language.RubySourceSection;
import org.jruby.truffle.language.arguments.MissingArgumentBehavior;
import org.jruby.truffle.language.arguments.ProfileArgumentNode;
import org.jruby.truffle.language.arguments.ReadBlockNode;
import org.jruby.truffle.language.arguments.ReadCallerFrameNode;
import org.jruby.truffle.language.arguments.ReadPreArgumentNode;
import org.jruby.truffle.language.arguments.ReadRemainingArgumentsNode;
import org.jruby.truffle.language.arguments.ReadSelfNode;
import org.jruby.truffle.language.methods.Arity;
import org.jruby.truffle.language.methods.ExceptionTranslatingNode;
import org.jruby.truffle.language.methods.InternalMethod;
import org.jruby.truffle.language.methods.SharedMethodInfo;
import org.jruby.truffle.language.objects.SelfNode;
import org.jruby.truffle.language.objects.SingletonClassNode;
import org.jruby.truffle.language.parser.jruby.Translator;
import org.jruby.truffle.platform.UnsafeGroup;
import org.jruby.truffle.tools.ChaosNodeGen;
import org.jruby.truffle.util.StringUtils;

import java.util.ArrayList;
@@ -54,23 +57,31 @@ public class CoreMethodNodeManager {
private static final boolean CHECK_AMBIGUOUS_OPTIONAL_ARGS = System.getenv("TRUFFLE_CHECK_AMBIGUOUS_OPTIONAL_ARGS") != null;
private final RubyContext context;
private final SingletonClassNode singletonClassNode;
private final PrimitiveManager primitiveManager;

public CoreMethodNodeManager(RubyContext context, SingletonClassNode singletonClassNode) {
public CoreMethodNodeManager(RubyContext context, SingletonClassNode singletonClassNode, PrimitiveManager primitiveManager) {
this.context = context;
this.singletonClassNode = singletonClassNode;
this.primitiveManager = primitiveManager;
}

public void addCoreMethodNodes(List<? extends NodeFactory<? extends RubyNode>> nodeFactories) {
final Class<?> firstNodeClass = nodeFactories.get(0).getClass().getAnnotation(GeneratedBy.class).value();
final String moduleName = firstNodeClass.getEnclosingClass().getAnnotation(CoreClass.class).value();
final DynamicObject module = getModule(moduleName);
String moduleName = null;
DynamicObject module = null;

for (NodeFactory<? extends RubyNode> nodeFactory : nodeFactories) {
final Class<?> nodeClass = nodeFactory.getClass().getAnnotation(GeneratedBy.class).value();
final CoreMethod methodAnnotation = nodeClass.getAnnotation(CoreMethod.class);
Primitive primitiveAnnotation;

if (methodAnnotation != null) {
if (module == null) {
moduleName = nodeClass.getEnclosingClass().getAnnotation(CoreClass.class).value();
module = getModule(moduleName);
}
addCoreMethod(module, new MethodDetails(moduleName, methodAnnotation, nodeFactory));
} else if ((primitiveAnnotation = nodeClass.getAnnotation(Primitive.class)) != null) {
primitiveManager.addPrimitive(nodeFactory, primitiveAnnotation);
}
}
}
@@ -175,29 +186,56 @@ private static CallTarget makeGenericMethod(RubyContext context, MethodDetails m
final CoreMethod method = methodDetails.getMethodAnnotation();

final SourceSection sourceSection = sharedMethodInfo.getSourceSection();
final int required = method.required();
final int optional = method.optional();
final RubySourceSection rubySourceSection = new RubySourceSection(sourceSection);

final RubyNode methodNode = createCoreMethodNode(context, sourceSection, methodDetails.getNodeFactory(), method);

if (CHECK_AMBIGUOUS_OPTIONAL_ARGS) {
AmbiguousOptionalArgumentChecker.verifyNoAmbiguousOptionalArguments(methodDetails);
}

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

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

RubyNode bodyNode = new ExceptionTranslatingNode(context, sourceSection, node, method.unsupportedOperationBehavior());

if (context.getOptions().CHAOS) {
bodyNode = ChaosNodeGen.create(bodyNode);
}

final RubyRootNode rootNode = new RubyRootNode(context, sourceSection, null, sharedMethodInfo, bodyNode, false);

return Truffle.getRuntime().createCallTarget(rootNode);
}

public static RubyNode createCoreMethodNode(RubyContext context, SourceSection sourceSection, NodeFactory<? extends RubyNode> nodeFactory, CoreMethod method) {
final List<RubyNode> argumentsNodes = new ArrayList<>();

if (method.needsCallerFrame()) {
argumentsNodes.add(new ReadCallerFrameNode());
}

// Do not use needsSelf=true in module functions, it is either the module/class or the instance.
// Usage of needsSelf is quite rare for singleton methods (except constructors).
final boolean needsSelf = method.constructor() || (!method.isModuleFunction() && !method.onSingleton() && method.needsSelf());
final boolean needsSelf = needsSelf(method);

if (needsSelf) {
RubyNode readSelfNode = new SelfNode(context, sourceSection);
argumentsNodes.add(transformArgument(method, readSelfNode, 0));
RubyNode readSelfNode = new ProfileArgumentNode(new ReadSelfNode());
argumentsNodes.add(transformArgument(context, sourceSection, method, readSelfNode, 0));
}

final int required = method.required();
final int optional = method.optional();
final int nArgs = required + optional;

for (int n = 0; n < nArgs; n++) {
RubyNode readArgumentNode = new ReadPreArgumentNode(n, MissingArgumentBehavior.UNDEFINED);
argumentsNodes.add(transformArgument(method, readArgumentNode, n + 1));
RubyNode readArgumentNode = new ProfileArgumentNode(new ReadPreArgumentNode(n, MissingArgumentBehavior.UNDEFINED));
argumentsNodes.add(transformArgument(context, sourceSection, method, readArgumentNode, n + 1));
}
if (method.rest()) {
argumentsNodes.add(new ReadRemainingArgumentsNode(nArgs));
@@ -207,8 +245,11 @@ private static CallTarget makeGenericMethod(RubyContext context, MethodDetails m
argumentsNodes.add(new ReadBlockNode(NotProvided.INSTANCE));
}

final RubyNode methodNode;
final NodeFactory<? extends RubyNode> nodeFactory = methodDetails.getNodeFactory();
return createNodeFromFactory(context, sourceSection, nodeFactory, argumentsNodes);
}

public static <T> T createNodeFromFactory(RubyContext context, SourceSection sourceSection, NodeFactory<? extends T> nodeFactory, List<RubyNode> argumentsNodes) {
final T methodNode;
List<List<Class<?>>> signatures = nodeFactory.getNodeSignatures();

assert signatures.size() == 1;
@@ -234,34 +275,22 @@ private static CallTarget makeGenericMethod(RubyContext context, MethodDetails m
}
}

if (CHECK_AMBIGUOUS_OPTIONAL_ARGS) {
AmbiguousOptionalArgumentChecker.verifyNoAmbiguousOptionalArguments(methodDetails);
}

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

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

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

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

return Truffle.getRuntime().createCallTarget(rootNode);
public static boolean needsSelf(CoreMethod method) {
// Do not use needsSelf=true in module functions, it is either the module/class or the instance.
// Usage of needsSelf is quite rare for singleton methods (except constructors).
return method.constructor() || (!method.isModuleFunction() && !method.onSingleton() && method.needsSelf());
}

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

if (n == 0 && method.raiseIfFrozenSelf()) {
argument = new RaiseIfFrozenNode(argument);
argument = new RaiseIfFrozenNode(context, sourceSection, argument);
}

return argument;
Original file line number Diff line number Diff line change
@@ -9,14 +9,13 @@
*/
package org.jruby.truffle.builtins;

import org.jruby.truffle.language.RubyNode;
import org.jruby.truffle.language.SnippetNode;
import org.jruby.truffle.language.arguments.RubyArguments;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.profiles.ConditionProfile;
import org.jruby.truffle.language.RubyNode;
import org.jruby.truffle.language.SnippetNode;
import org.jruby.truffle.language.arguments.RubyArguments;

public class EnumeratorSizeNode extends RubyNode {

@@ -26,7 +25,6 @@ public class EnumeratorSizeNode extends RubyNode {
private final String snippet;

public EnumeratorSizeNode(String enumeratorSize, String methodName, RubyNode method) {
super(method.getContext(), method.getEncapsulatingSourceSection());
this.method = method;
this.snippet = "to_enum(:" + methodName + ") { " + enumeratorSize + " }";
}
Original file line number Diff line number Diff line change
@@ -9,13 +9,10 @@
*/
package org.jruby.truffle.builtins;

import com.oracle.truffle.api.dsl.GeneratedBy;
import com.oracle.truffle.api.dsl.NodeFactory;
import org.jruby.truffle.core.rubinius.UndefinedPrimitiveNodes;
import org.jruby.truffle.language.RubyNode;


import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@@ -36,15 +33,7 @@ public PrimitiveNodeConstructor getPrimitive(String name) {
return constructor;
}

public void addPrimitiveNodes(List<? extends NodeFactory<? extends RubyNode>> nodeFactories) {
for (NodeFactory<? extends RubyNode> nodeFactory : nodeFactories) {
final GeneratedBy generatedBy = nodeFactory.getClass().getAnnotation(GeneratedBy.class);
final Class<?> nodeClass = generatedBy.value();
final Primitive annotation = nodeClass.getAnnotation(Primitive.class);

if (annotation != null) {
primitives.put(annotation.name(), new PrimitiveNodeConstructor(annotation, nodeFactory));
}
}
public void addPrimitive(NodeFactory<? extends RubyNode> nodeFactory, Primitive annotation) {
primitives.put(annotation.name(), new PrimitiveNodeConstructor(annotation, nodeFactory));
}
}
Original file line number Diff line number Diff line change
@@ -16,9 +16,10 @@
import org.jruby.truffle.core.numeric.FixnumLowerNodeGen;
import org.jruby.truffle.language.RubyNode;
import org.jruby.truffle.language.arguments.MissingArgumentBehavior;
import org.jruby.truffle.language.arguments.ProfileArgumentNode;
import org.jruby.truffle.language.arguments.ReadPreArgumentNode;
import org.jruby.truffle.language.arguments.ReadSelfNode;
import org.jruby.truffle.language.control.ReturnID;
import org.jruby.truffle.language.objects.SelfNode;

import java.util.ArrayList;
import java.util.List;
@@ -46,12 +47,12 @@ public RubyNode createCallPrimitiveNode(RubyContext context, SourceSection sourc
List<Class<?>> signature = signatures.get(0);

if (annotation.needsSelf()) {
arguments.add(transformArgument(new SelfNode(context, sourceSection), 0));
arguments.add(transformArgument(new ProfileArgumentNode(new ReadSelfNode()), 0));
argumentsCount--;
}

for (int n = 0; n < argumentsCount; n++) {
RubyNode readArgumentNode = new ReadPreArgumentNode(n, MissingArgumentBehavior.UNDEFINED);
RubyNode readArgumentNode = new ProfileArgumentNode(new ReadPreArgumentNode(n, MissingArgumentBehavior.UNDEFINED));
arguments.add(transformArgument(readArgumentNode, n + 1));
}

Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@
package org.jruby.truffle.builtins;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.profiles.ConditionProfile;
@@ -21,15 +22,15 @@

public class ReturnEnumeratorIfNoBlockNode extends RubyNode {

private final String methodName;
@Child private RubyNode method;
@Child private CallDispatchHeadNode toEnumNode;
private final DynamicObject methodSymbol;
@CompilationFinal private DynamicObject methodSymbol;
private final ConditionProfile noBlockProfile = ConditionProfile.createBinaryProfile();

public ReturnEnumeratorIfNoBlockNode(String methodName, RubyNode method) {
super(method.getContext(), method.getEncapsulatingSourceSection());
this.methodName = methodName;
this.method = method;
this.methodSymbol = getSymbol(methodName);
}

@Override
@@ -42,6 +43,11 @@ public Object execute(VirtualFrame frame) {
toEnumNode = insert(DispatchHeadNodeFactory.createMethodCall(getContext()));
}

if (methodSymbol == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
methodSymbol = getSymbol(methodName);
}

final Object[] arguments = ArrayUtils.unshift(RubyArguments.getArguments(frame), methodSymbol);
return toEnumNode.call(frame, RubyArguments.getSelf(frame), "to_enum", arguments);
} else {
283 changes: 141 additions & 142 deletions truffle/src/main/java/org/jruby/truffle/core/CoreLibrary.java

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions truffle/src/main/java/org/jruby/truffle/core/MathNodes.java
Original file line number Diff line number Diff line change
@@ -329,7 +329,7 @@ public DynamicObject frexp(double a) {
for (; mantissa >= 1.0; mantissa *= 0.5, exponent +=1) { }
}

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

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

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

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

@Fallback
4 changes: 2 additions & 2 deletions truffle/src/main/java/org/jruby/truffle/core/ObjectNodes.java
Original file line number Diff line number Diff line change
@@ -123,15 +123,15 @@ public ObjectInfectPrimitiveNode(RubyContext context, SourceSection sourceSectio
public Object objectInfect(Object host, Object source) {
if (isTaintedNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
isTaintedNode = insert(IsTaintedNodeGen.create(getContext(), getSourceSection(), null));
isTaintedNode = insert(IsTaintedNodeGen.create(getContext(), null, null));
}

if (isTaintedNode.executeIsTainted(source)) {
// This lazy node allocation effectively gives us a branch profile

if (taintNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
taintNode = insert(TaintNodeGen.create(getContext(), getSourceSection(), null));
taintNode = insert(TaintNodeGen.create(getContext(), null, null));
}

taintNode.executeTaint(host);
Original file line number Diff line number Diff line change
@@ -12,6 +12,8 @@

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.language.RubyNode;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.language.objects.IsFrozenNode;
@@ -24,10 +26,10 @@ public class RaiseIfFrozenNode extends RubyNode {
@Child private RubyNode child;
@Child private IsFrozenNode isFrozenNode;

public RaiseIfFrozenNode(RubyNode child) {
super(child.getContext(), child.getEncapsulatingSourceSection());
public RaiseIfFrozenNode(RubyContext context, SourceSection sourceSection, RubyNode child) {
super(context, sourceSection);
this.child = child;
isFrozenNode = IsFrozenNodeGen.create(child.getContext(), child.getEncapsulatingSourceSection(), null);
isFrozenNode = IsFrozenNodeGen.create(context, sourceSection, null);
}

@Override
Original file line number Diff line number Diff line change
@@ -18,11 +18,12 @@
import org.jruby.truffle.builtins.CoreMethod;
import org.jruby.truffle.builtins.CoreMethodArrayArgumentsNode;
import org.jruby.truffle.core.array.ArrayOperations;
import org.jruby.truffle.core.hash.KeyValue;
import org.jruby.truffle.core.hash.HashOperations;
import org.jruby.truffle.core.hash.KeyValue;
import org.jruby.truffle.core.string.StringOperations;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.platform.UnsafeGroup;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
Original file line number Diff line number Diff line change
@@ -369,7 +369,7 @@ public DynamicObject times() {
final double tutime = 0;
final double tstime = 0;

return Layouts.ARRAY.createArray(coreLibrary().getArrayFactory(), new double[]{
return createArray(new double[] {
utime,
stime,
cutime,
@@ -465,11 +465,11 @@ public DynamicObject getSection(DynamicObject section) {
Object[] objects = new Object[]{
createString(StringOperations.encodeRope(key, UTF8Encoding.INSTANCE)),
createString(StringOperations.encodeRope(stringValue, UTF8Encoding.INSTANCE)) };
sectionKeyValues.add(Layouts.ARRAY.createArray(coreLibrary().getArrayFactory(), objects, objects.length));
sectionKeyValues.add(createArray(objects, objects.length));
}

Object[] objects = sectionKeyValues.toArray();
return Layouts.ARRAY.createArray(coreLibrary().getArrayFactory(), objects, objects.length);
return createArray(objects, objects.length);
}

}
@@ -535,7 +535,7 @@ public Integer block() throws InterruptedException {
}

Object[] objects = new Object[]{ output, termsig, stopsig, pid };
return Layouts.ARRAY.createArray(coreLibrary().getArrayFactory(), objects, objects.length);
return createArray(objects, objects.length);
}

}
Original file line number Diff line number Diff line change
@@ -19,8 +19,6 @@
import org.jruby.truffle.language.RubyGuards;
import org.jruby.truffle.language.RubyNode;

import static org.jruby.truffle.core.array.ArrayHelpers.createArray;

/**
* Concatenate argument arrays (translating a org.jruby.ast.ArgsCatNode).
*/
@@ -63,7 +61,7 @@ private DynamicObject executeSingle(VirtualFrame frame) {
store = arrayBuilderNode.ensure(store, 1);
store = arrayBuilderNode.appendValue(store, 0, childObject);
}
return createArray(getContext(), arrayBuilderNode.finish(store, size), size);
return createArray(arrayBuilderNode.finish(store, size), size);
}

@ExplodeLoop
@@ -87,7 +85,7 @@ private DynamicObject executeMultiple(VirtualFrame frame) {
}
}

return createArray(getContext(), arrayBuilderNode.finish(store, length), length);
return createArray(arrayBuilderNode.finish(store, length), length);
}

@ExplodeLoop
Original file line number Diff line number Diff line change
@@ -21,8 +21,6 @@
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.language.RubyNode;

import static org.jruby.truffle.core.array.ArrayHelpers.createArray;

@NodeChildren({ @NodeChild(value = "array", type = RubyNode.class) })
@ImportStatic(ArrayGuards.class)
public abstract class ArrayDropTailNode extends RubyNode {
@@ -36,7 +34,7 @@ public ArrayDropTailNode(RubyContext context, SourceSection sourceSection, int i

@Specialization(guards = "isNullArray(array)")
public DynamicObject getHeadNull(DynamicObject array) {
return createArray(getContext(), null, 0);
return createArray(null, 0);
}

@Specialization(guards = "strategy.matches(array)", limit = "ARRAY_STRATEGIES")
@@ -45,11 +43,11 @@ public DynamicObject dropTail(DynamicObject array,
@Cached("createBinaryProfile()") ConditionProfile indexLargerThanSize) {
final int size = Layouts.ARRAY.getSize(array);
if (indexLargerThanSize.profile(index >= size)) {
return createArray(getContext(), null, 0);
return createArray(null, 0);
} else {
final int newSize = size - index;
final Object newStore = strategy.newMirror(array).extractRange(0, newSize).getArray();
return createArray(getContext(), newStore, newSize);
return createArray(newStore, newSize);
}
}

Original file line number Diff line number Diff line change
@@ -20,7 +20,6 @@
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.language.RubyNode;
import org.jruby.truffle.language.objects.AllocateObjectNode;
import org.jruby.truffle.language.objects.AllocateObjectNodeGen;

/**
* Dup an array, without using any method lookup. This isn't a call - it's an operation on a core class.
Original file line number Diff line number Diff line change
@@ -21,8 +21,6 @@
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.language.RubyNode;

import static org.jruby.truffle.core.array.ArrayHelpers.createArray;

@NodeChildren({@NodeChild(value = "array", type = RubyNode.class)})
@ImportStatic(ArrayGuards.class)
public abstract class ArrayGetTailNode extends RubyNode {
@@ -36,7 +34,7 @@ public ArrayGetTailNode(RubyContext context, SourceSection sourceSection, int in

@Specialization(guards = "isNullArray(array)")
public DynamicObject getTailNull(DynamicObject array) {
return createArray(getContext(), null, 0);
return createArray(null, 0);
}

@Specialization(guards = "strategy.matches(array)", limit = "ARRAY_STRATEGIES")
@@ -45,10 +43,10 @@ public DynamicObject getTail(DynamicObject array,
@Cached("createBinaryProfile()") ConditionProfile indexLargerThanSize) {
final int size = Layouts.ARRAY.getSize(array);
if (indexLargerThanSize.profile(index >= size)) {
return createArray(getContext(), null, 0);
return createArray(null, 0);
} else {
final Object newStore = strategy.newMirror(array).extractRange(index, size).getArray();
return createArray(getContext(), newStore, size - index);
return createArray(newStore, size - index);
}
}

Original file line number Diff line number Diff line change
@@ -15,33 +15,33 @@
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.Layouts;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.CoreLibrary;
import org.jruby.truffle.language.RubyNode;
import org.jruby.truffle.language.RubySourceSection;
import org.jruby.truffle.language.objects.AllocateObjectNode;
import org.jruby.truffle.language.objects.AllocateObjectNodeGen;

public abstract class ArrayLiteralNode extends RubyNode {

public static ArrayLiteralNode create(RubyContext context, SourceSection sourceSection, RubyNode[] values) {
public static ArrayLiteralNode create(RubyContext context, RubySourceSection sourceSection, RubyNode[] values) {
return new UninitialisedArrayLiteralNode(context, sourceSection, values);
}

@Children protected final RubyNode[] values;
@Child protected AllocateObjectNode allocateObjectNode;

public ArrayLiteralNode(RubyContext context, SourceSection sourceSection, RubyNode[] values) {
public ArrayLiteralNode(RubyContext context, RubySourceSection sourceSection, RubyNode[] values) {
super(context, sourceSection);
this.values = values;
this.allocateObjectNode = AllocateObjectNodeGen.create(context, sourceSection, false, null, null);
this.allocateObjectNode = AllocateObjectNodeGen.create(context, (RubySourceSection) null, false, null, null);
}

protected DynamicObject makeGeneric(VirtualFrame frame, Object[] alreadyExecuted) {
CompilerAsserts.neverPartOfCompilation();

replace(new ObjectArrayLiteralNode(getContext(), getSourceSection(), values));
replace(new ObjectArrayLiteralNode(getContext(), getRubySourceSection(), values));

final Object[] executedValues = new Object[values.length];

@@ -96,7 +96,7 @@ public RubyNode stealNode(int index) {

private static class EmptyArrayLiteralNode extends ArrayLiteralNode {

public EmptyArrayLiteralNode(RubyContext context, SourceSection sourceSection, RubyNode[] values) {
public EmptyArrayLiteralNode(RubyContext context, RubySourceSection sourceSection, RubyNode[] values) {
super(context, sourceSection, values);
}

@@ -109,7 +109,7 @@ public Object execute(VirtualFrame frame) {

private static class FloatArrayLiteralNode extends ArrayLiteralNode {

public FloatArrayLiteralNode(RubyContext context, SourceSection sourceSection, RubyNode[] values) {
public FloatArrayLiteralNode(RubyContext context, RubySourceSection sourceSection, RubyNode[] values) {
super(context, sourceSection, values);
}

@@ -143,7 +143,7 @@ private DynamicObject makeGeneric(VirtualFrame frame, final double[] executedVal

private static class IntegerArrayLiteralNode extends ArrayLiteralNode {

public IntegerArrayLiteralNode(RubyContext context, SourceSection sourceSection, RubyNode[] values) {
public IntegerArrayLiteralNode(RubyContext context, RubySourceSection sourceSection, RubyNode[] values) {
super(context, sourceSection, values);
}

@@ -177,7 +177,7 @@ private DynamicObject makeGeneric(VirtualFrame frame, final int[] executedValues

private static class LongArrayLiteralNode extends ArrayLiteralNode {

public LongArrayLiteralNode(RubyContext context, SourceSection sourceSection, RubyNode[] values) {
public LongArrayLiteralNode(RubyContext context, RubySourceSection sourceSection, RubyNode[] values) {
super(context, sourceSection, values);
}

@@ -211,7 +211,7 @@ private DynamicObject makeGeneric(VirtualFrame frame, final long[] executedValue

private static class ObjectArrayLiteralNode extends ArrayLiteralNode {

public ObjectArrayLiteralNode(RubyContext context, SourceSection sourceSection, RubyNode[] values) {
public ObjectArrayLiteralNode(RubyContext context, RubySourceSection sourceSection, RubyNode[] values) {
super(context, sourceSection, values);
}

@@ -231,7 +231,7 @@ public Object execute(VirtualFrame frame) {

private static class UninitialisedArrayLiteralNode extends ArrayLiteralNode {

public UninitialisedArrayLiteralNode(RubyContext context, SourceSection sourceSection, RubyNode[] values) {
public UninitialisedArrayLiteralNode(RubyContext context, RubySourceSection sourceSection, RubyNode[] values) {
super(context, sourceSection, values);
}

@@ -249,15 +249,15 @@ public Object execute(VirtualFrame frame) {
final Object store = Layouts.ARRAY.getStore(array);

if (store == null) {
replace(new EmptyArrayLiteralNode(getContext(), getSourceSection(), values));
replace(new EmptyArrayLiteralNode(getContext(), getRubySourceSection(), values));
} if (store instanceof int[]) {
replace(new IntegerArrayLiteralNode(getContext(), getSourceSection(), values));
replace(new IntegerArrayLiteralNode(getContext(), getRubySourceSection(), values));
} else if (store instanceof long[]) {
replace(new LongArrayLiteralNode(getContext(), getSourceSection(), values));
replace(new LongArrayLiteralNode(getContext(), getRubySourceSection(), values));
} else if (store instanceof double[]) {
replace(new FloatArrayLiteralNode(getContext(), getSourceSection(), values));
replace(new FloatArrayLiteralNode(getContext(), getRubySourceSection(), values));
} else {
replace(new ObjectArrayLiteralNode(getContext(), getSourceSection(), values));
replace(new ObjectArrayLiteralNode(getContext(), getRubySourceSection(), values));
}

return array;
Loading

0 comments on commit 990319d

Please sign in to comment.