Skip to content
Permalink

Comparing changes

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

Open a pull request

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

Commits on Mar 14, 2016

  1. Copy the full SHA
    7428442 View commit details
  2. Copy the full SHA
    849d30d View commit details
  3. Copy the full SHA
    992962d View commit details
  4. Copy the full SHA
    bb470cb View commit details
  5. Copy the full SHA
    a347cd3 View commit details
  6. Copy the full SHA
    cf62adb View commit details
  7. 2
    Copy the full SHA
    60a2a84 View commit details
  8. [Truffle] j+tr: formatting

    pitr-ch committed Mar 14, 2016
    Copy the full SHA
    0d786cd View commit details
  9. Copy the full SHA
    bb2fa00 View commit details
2 changes: 1 addition & 1 deletion lib/ruby/truffle/jruby+truffle/bin/jruby+truffle
Original file line number Diff line number Diff line change
@@ -2,5 +2,5 @@

require_relative '../lib/runner.rb'

runner = JRubyTruffleRunner.new
runner = JRubyTruffleRunner.new ARGV
exit runner.run
7 changes: 7 additions & 0 deletions lib/ruby/truffle/jruby+truffle/gem_ci/algebrick.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
git_clone 'https://github.com/pitr-ch/algebrick.git' unless File.exists? repository_dir
git_checkout git_tag '0.7.3'

has_to_succeed setup

result run(%w[test/algebrick_test.rb], raise: false)

1 change: 1 addition & 0 deletions lib/ruby/truffle/jruby+truffle/gem_ci/travis.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
activesupport
algebrick
21 changes: 14 additions & 7 deletions lib/ruby/truffle/jruby+truffle/lib/runner.rb
Original file line number Diff line number Diff line change
@@ -228,7 +228,7 @@ module OptionBlocks
end


def initialize(argv = ARGV)
def initialize(argv)
@options = construct_default_options
@option_parsers = build_option_parsers

@@ -335,6 +335,9 @@ def construct_default_options
def self.default_option_values(group_options)
group_options.each_with_object({}) do |(option, data), group_option_defaults|
*args, block, default = data
unless [TrueClass, FalseClass, NilClass, Fixnum].any? { |v| v === default }
default = default.clone
end
group_option_defaults[option] = default
end
end
@@ -449,9 +452,12 @@ def subcommand_run(rest)

core_load_path = jruby_path.join 'truffle/src/main/ruby'

missing_core_load_path = !File.exists?(core_load_path)
puts "Core load path: #{core_load_path} does not exist, fallbacking to --no-use-fs-core" if missing_core_load_path

truffle_options = [
('-X+T'),
("-Xtruffle.core.load_path=#{core_load_path}" if @options[:global][:use_fs_core]),
("-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])
]

@@ -509,13 +515,13 @@ def subcommand_ci(rest)
rest = option_parser.order line.split

gem_name = rest.first
CIEnvironment.new(@options[:global][:dir], gem_name, rest[1..-1]).success?
CIEnvironment.new(@options[:global][:dir], gem_name, rest[1..-1], verbose: verbose?).success?
end

results.all?
else
gem_name = rest.first
ci = CIEnvironment.new @options[:global][:dir], gem_name, rest[1..-1], definition: options[:ci][:definition]
ci = CIEnvironment.new @options[:global][:dir], gem_name, rest[1..-1], definition: options[:ci][:definition], verbose: verbose?
ci.success?
end
end
@@ -549,10 +555,11 @@ def self.define_dsl_attr(*names, &conversion)
define_dsl_attr(:working_dir) { |v| Pathname(v) }
attr_reader :gem_name

def initialize(working_dir, gem_name, rest, definition: nil)
def initialize(working_dir, gem_name, rest, definition: nil, verbose: false)
@options = {}
@gem_name = gem_name
@rest = rest
@verbose = verbose

@working_dir = Pathname(working_dir)
@repository_name = gem_name
@@ -652,7 +659,7 @@ def git_tags
end

def setup
Dir.chdir(testing_dir) { JRubyTruffleRunner.new(['setup']).run }
Dir.chdir(testing_dir) { JRubyTruffleRunner.new([('-v' if @verbose), 'setup'].compact).run }
end

def cancel_ci!(result = false)
@@ -665,7 +672,7 @@ def has_to_succeed(result)

def run(options, raise: true)
raise ArgumentError unless options.is_a? Array
Dir.chdir(testing_dir) { JRubyTruffleRunner.new(['run', *options]).run }
Dir.chdir(testing_dir) { JRubyTruffleRunner.new([('-v' if @verbose), 'run', *options].compact).run }
end

def execute(cmd, dir: testing_dir, raise: true)
3 changes: 3 additions & 0 deletions lib/ruby/truffle/shims/openssl-stubs.rb
Original file line number Diff line number Diff line change
@@ -52,6 +52,9 @@ def update(data)
iv_byte = @iv[(iv_i*2)..(iv_i*2+1)].to_i(16)
(byte ^ iv_byte).chr
end.join
rescue => e
# puts format "%s (%s)\n%s", e.message, e.class, e.backtrace.join("\n")
raise CipherError
end

def final
8 changes: 8 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/RubyContext.java
Original file line number Diff line number Diff line change
@@ -53,6 +53,8 @@
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class RubyContext extends ExecutionContext {

@@ -89,6 +91,8 @@ public class RubyContext extends ExecutionContext {
private final CallGraph callGraph;
private final PrintStream debugStandardOut;

private final Object classVariableDefinitionLock = new Object();

private org.jruby.ast.RootNode initialJRubyRootNode;

public RubyContext(Ruby jrubyRuntime, TruffleLanguage.Env env) {
@@ -322,4 +326,8 @@ public CallStackManager getCallStack() {
public CoreStrings getCoreStrings() {
return coreStrings;
}

public Object getClassVariableDefinitionLock() {
return classVariableDefinitionLock;
}
}
Original file line number Diff line number Diff line change
@@ -43,6 +43,7 @@
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class ModuleFields implements ModuleChain, ObjectGraphNode {

@@ -75,8 +76,8 @@ public static void debugModuleChain(DynamicObject module) {
private String name = null;

private final Map<String, InternalMethod> methods = new ConcurrentHashMap<>();
private final Map<String, RubyConstant> constants = new ConcurrentHashMap<>();
private final Map<String, Object> classVariables = new ConcurrentHashMap<>();
private final ConcurrentMap<String, RubyConstant> constants = new ConcurrentHashMap<>();
private final ConcurrentMap<String, Object> classVariables = new ConcurrentHashMap<>();

private final CyclicAssumption unmodifiedAssumption;

@@ -295,12 +296,16 @@ public void setConstantInternal(RubyContext context, Node currentNode, String na
// TODO(CS): warn when redefining a constant
// TODO (nirvdrum 18-Feb-15): But don't warn when redefining an autoloaded constant.

final RubyConstant previous = constants.get(name);
final boolean isPrivate = previous != null && previous.isPrivate();
while (true) {
final RubyConstant previous = constants.get(name);
final boolean isPrivate = previous != null && previous.isPrivate();
final RubyConstant newValue = new RubyConstant(rubyModuleObject, value, isPrivate, autoload);

constants.put(name, new RubyConstant(rubyModuleObject, value, isPrivate, autoload));

newLexicalVersion();
if ((previous == null) ? (constants.putIfAbsent(name, newValue) == null) : constants.replace(name, previous, newValue)) {
newLexicalVersion();
break;
}
}
}

@TruffleBoundary
@@ -311,25 +316,6 @@ public RubyConstant removeConstant(RubyContext context, Node currentNode, String
return oldConstant;
}

@TruffleBoundary
public void setClassVariable(RubyContext context, Node currentNode, String variableName, Object value) {
checkFrozen(context, currentNode);

classVariables.put(variableName, value);
}

@TruffleBoundary
public Object removeClassVariable(RubyContext context, Node currentNode, String name) {
checkFrozen(context, currentNode);

final Object found = classVariables.remove(name);
if (found == null) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(context.getCoreLibrary().nameErrorClassVariableNotDefined(name, rubyModuleObject, currentNode));
}
return found;
}

@TruffleBoundary
public void addMethod(RubyContext context, Node currentNode, InternalMethod method) {
assert ModuleOperations.canBindMethodTo(method.getDeclaringModule(), rubyModuleObject) ||
@@ -417,13 +403,18 @@ public void alias(RubyContext context, Node currentNode, String newName, String
@TruffleBoundary
public void changeConstantVisibility(RubyContext context, Node currentNode, String name, boolean isPrivate) {
checkFrozen(context, currentNode);
RubyConstant rubyConstant = constants.get(name);

if (rubyConstant != null) {
rubyConstant.setPrivate(isPrivate);
newLexicalVersion();
} else {
throw new RaiseException(context.getCoreLibrary().nameErrorUninitializedConstant(rubyModuleObject, name, currentNode));
while (true) {
final RubyConstant previous = constants.get(name);

if (previous == null) {
throw new RaiseException(context.getCoreLibrary().nameErrorUninitializedConstant(rubyModuleObject, name, currentNode));
}

if (constants.replace(name, previous, previous.withPrivate(isPrivate))) {
newLexicalVersion();
break;
}
}
}

@@ -527,7 +518,7 @@ public Map<String, InternalMethod> getMethods() {
return methods;
}

public Map<String, Object> getClassVariables() {
public ConcurrentMap<String, Object> getClassVariables() {
return classVariables;
}

Original file line number Diff line number Diff line change
@@ -1847,7 +1847,7 @@ public RubyNode coerceToString(RubyNode name) {
@Specialization
public Object removeClassVariableString(DynamicObject module, String name) {
SymbolTable.checkClassVariableName(getContext(), name, this);
return Layouts.MODULE.getFields(module).removeClassVariable(getContext(), this, name);
return ModuleOperations.removeClassVariable(Layouts.MODULE.getFields(module), getContext(), this, name);
}

}
Original file line number Diff line number Diff line change
@@ -357,23 +357,44 @@ public Object apply(DynamicObject module) {
@TruffleBoundary
public static void setClassVariable(final RubyContext context, DynamicObject module, final String name, final Object value, final Node currentNode) {
assert RubyGuards.isRubyModule(module);
ModuleFields moduleFields = Layouts.MODULE.getFields(module);
moduleFields.checkFrozen(context, currentNode);

// if the cvar is not already defined we need to take lock and ensure there is only one
// defined in the class tree
if (trySetClassVariable(module, name, value) == null) {
synchronized (context.getClassVariableDefinitionLock()) {
if (trySetClassVariable(module, name, value) == null) {
moduleFields.getClassVariables().put(name, value);
}
}
}
}

DynamicObject found = classVariableLookup(module, new Function1<DynamicObject, DynamicObject>() {
private static DynamicObject trySetClassVariable(DynamicObject module, final String name, final Object value) {
final ModuleFields moduleFields = Layouts.MODULE.getFields(module);
return classVariableLookup(module, new Function1<DynamicObject, DynamicObject>() {
@Override
public DynamicObject apply(DynamicObject module) {
if (Layouts.MODULE.getFields(module).getClassVariables().containsKey(name)) {
Layouts.MODULE.getFields(module).setClassVariable(context, currentNode, name, value);
if (moduleFields.getClassVariables().putIfAbsent(name, value) == null) {
return module;
} else {
return null;
}
}
});
}

@TruffleBoundary
public static Object removeClassVariable(ModuleFields moduleFields, RubyContext context, Node currentNode, String name) {
moduleFields.checkFrozen(context, currentNode);

final Object found = moduleFields.getClassVariables().remove(name);
if (found == null) {
// Not existing class variable - set in the current module
Layouts.MODULE.getFields(module).setClassVariable(context, currentNode, name, value);
CompilerDirectives.transferToInterpreter();
throw new RaiseException(context.getCoreLibrary().nameErrorClassVariableNotDefined(name, moduleFields.rubyModuleObject, currentNode));
}
return found;
}

private static <R> R classVariableLookup(DynamicObject module, Function1<R, DynamicObject> action) {
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ public class RubyConstant {

private final DynamicObject declaringModule;
private final Object value;
private boolean isPrivate;
private final boolean isPrivate;
private final boolean autoload;

public RubyConstant(DynamicObject declaringModule, Object value, boolean isPrivate, boolean autoload) {
@@ -41,8 +41,12 @@ public boolean isPrivate() {
return isPrivate;
}

public void setPrivate(boolean isPrivate) {
this.isPrivate = isPrivate;
public RubyConstant withPrivate(boolean isPrivate) {
if (isPrivate == this.isPrivate) {
return this;
} else {
return new RubyConstant(declaringModule, value, isPrivate, autoload);
}
}

public boolean isVisibleTo(RubyContext context, LexicalScope lexicalScope, DynamicObject module) {