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: df70f289f15d
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: c4dae0b5e426
Choose a head ref
  • 3 commits
  • 17 files changed
  • 1 contributor

Commits on May 18, 2015

  1. 6
    Copy the full SHA
    0d4f775 View commit details
  2. Copy the full SHA
    5df8160 View commit details
  3. Copy the full SHA
    c4dae0b View commit details
52 changes: 52 additions & 0 deletions lib/ruby/truffle/truffle/digest.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
# code is released under a tri EPL/GPL/LGPL license. You can use it,
# redistribute it and/or modify it under the terms of the:
#
# Eclipse Public License version 1.0
# GNU General Public License version 2
# GNU Lesser General Public License version 2.1

module Digest

class Base

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

alias_method :<<, :update

def reset
Truffle::Digest.reset @digest
end

def digest(message=nil)
# TODO CS 18-May-15 need to properly handle missing argument, not pretend it's nil
if message.nil?
Truffle::Digest.digest @digest
else
reset
update message
digested = digest
reset
digested
end
end

end

class MD5 < Base

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

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

end

end
1 change: 1 addition & 0 deletions lib/ruby/truffle/truffle/digest/md5.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require 'digest'
1 change: 1 addition & 0 deletions spec/truffle/tags/library/digest/md5/block_length_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Digest::MD5#block_length returns the length of digest block
1 change: 1 addition & 0 deletions spec/truffle/tags/library/digest/md5/digest_bang_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Digest::MD5#digest! returns a digest and can digest!
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Digest::MD5#digest_length returns the length of computed digests
3 changes: 3 additions & 0 deletions spec/truffle/tags/library/digest/md5/equal_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fails:Digest::MD5#== equals the string representing its hexdigest
fails:Digest::MD5#== equals the appropriate object that responds to to_str
fails:Digest::MD5#== equals the same digest for a different object
6 changes: 6 additions & 0 deletions spec/truffle/tags/library/digest/md5/file_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fails:Digest::MD5.file when passed a path to a file that exists returns a Digest::MD5 object
fails:Digest::MD5.file when passed a path to a file that exists returns a Digest::MD5 object with the correct digest
fails:Digest::MD5.file when passed a path to a file that exists calls #to_str on an object and returns the Digest::MD5 with the result
fails:Digest::MD5.file raises an Errno::EISDIR when passed a path that is a directory
fails:Digest::MD5.file raises a Errno::ENOENT when passed a path that does not exist
fails:Digest::MD5.file raises a TypeError when passed nil
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Digest::MD5#hexdigest! returns a hexdigest and resets the state
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/digest/md5/hexdigest_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:Digest::MD5#hexdigest returns a hexdigest
fails:Digest::MD5.hexdigest returns a hexdigest
1 change: 1 addition & 0 deletions spec/truffle/tags/library/digest/md5/inspect_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Digest::MD5#inspect returns a Ruby object representation
1 change: 1 addition & 0 deletions spec/truffle/tags/library/digest/md5/length_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Digest::MD5#length returns the length of the digest
1 change: 1 addition & 0 deletions spec/truffle/tags/library/digest/md5/size_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:Digest::MD5#size returns the length of the digest
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/digest/md5/to_s_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:Digest::MD5#to_s returns a hexdigest
fails:Digest::MD5#to_s does not change the internal state
6 changes: 5 additions & 1 deletion spec/truffle/truffle.mspec
Original file line number Diff line number Diff line change
@@ -95,6 +95,7 @@ class MSpecScript
"spec/ruby/library/date",
"spec/ruby/library/datetime",
"spec/ruby/library/delegate",
"spec/ruby/library/digest/md5",
"spec/ruby/library/cgi",
"spec/ruby/library/erb",
"spec/ruby/library/getoptlong",
@@ -123,7 +124,10 @@ class MSpecScript
"^spec/ruby/library/bigdecimal",
"^spec/ruby/library/continuation",
"^spec/ruby/library/csv",
"^spec/ruby/library/digest",
"^spec/ruby/library/digest/sha1",
"^spec/ruby/library/digest/sha256",
"^spec/ruby/library/digest/sha384",
"^spec/ruby/library/digest/sha512",
"^spec/ruby/library/drb",
"^spec/ruby/library/etc",
"^spec/ruby/library/expect",
120 changes: 120 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/nodes/ext/DigestNodes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.nodes.ext;

import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.object.*;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.core.CoreClass;
import org.jruby.truffle.nodes.core.CoreMethod;
import org.jruby.truffle.nodes.core.CoreMethodArrayArgumentsNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.util.ByteList;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.EnumSet;

@CoreClass(name = "Truffle::Digest")
public abstract class DigestNodes {

private static final HiddenKey DIGEST_IDENTIFIER = new HiddenKey("digest");
private static final Property DIGEST_PROPERTY;
private static final DynamicObjectFactory DIGEST_FACTORY;

static {
final Shape.Allocator allocator = RubyBasicObject.LAYOUT.createAllocator();
DIGEST_PROPERTY = Property.create(DIGEST_IDENTIFIER, allocator.locationForType(MessageDigest.class, EnumSet.of(LocationModifier.NonNull, LocationModifier.Final)), 0);
DIGEST_FACTORY = RubyBasicObject.EMPTY_SHAPE.addProperty(DIGEST_PROPERTY).createFactory();
}

private enum Algorithm {
MD5
}

private static RubyBasicObject createDigest(RubyContext context, Algorithm algorithm) {
final MessageDigest digest;

try {
digest = MessageDigest.getInstance(algorithm.name());
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}

return new RubyBasicObject(context.getCoreLibrary().getObjectClass(), DIGEST_FACTORY.newInstance(digest));
}

public static MessageDigest getDigest(RubyBasicObject digest) {
assert digest.getDynamicObject().getShape().hasProperty(DIGEST_IDENTIFIER);
return (MessageDigest) DIGEST_PROPERTY.get(digest.getDynamicObject(), true);
}

@CoreMethod(names = "md5", isModuleFunction = true)
public abstract static class MD5Node extends CoreMethodArrayArgumentsNode {

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

@Specialization
public RubyBasicObject md5() {
return createDigest(getContext(), Algorithm.MD5);
}

}

@CoreMethod(names = "update", isModuleFunction = true, required = 2)
public abstract static class UpdateNode extends CoreMethodArrayArgumentsNode {

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

@Specialization
public RubyBasicObject update(RubyBasicObject digestObject, RubyString message) {
final ByteList bytes = message.getByteList();
getDigest(digestObject).update(bytes.getUnsafeBytes(), bytes.begin(), bytes.length());
return digestObject;
}

}

@CoreMethod(names = "reset", isModuleFunction = true, required = 1)
public abstract static class ResetNode extends CoreMethodArrayArgumentsNode {

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

@Specialization
public RubyBasicObject reset(RubyBasicObject digestObject) {
getDigest(digestObject).reset();
return digestObject;
}

}

@CoreMethod(names = "digest", isModuleFunction = true, required = 1)
public abstract static class DigestNode extends CoreMethodArrayArgumentsNode {

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

@Specialization
public RubyString digest(RubyBasicObject digestObject) {
return getContext().makeString(getDigest(digestObject).digest());
}

}

}
Original file line number Diff line number Diff line change
@@ -30,6 +30,7 @@
import org.jruby.truffle.nodes.core.array.ArrayNodesFactory;
import org.jruby.truffle.nodes.core.fixnum.FixnumNodesFactory;
import org.jruby.truffle.nodes.core.hash.HashNodesFactory;
import org.jruby.truffle.nodes.ext.DigestNodesFactory;
import org.jruby.truffle.nodes.objects.Allocator;
import org.jruby.truffle.nodes.objects.FreezeNode;
import org.jruby.truffle.nodes.objects.FreezeNodeGen;
@@ -340,6 +341,7 @@ public CoreLibrary(RubyContext context) {
defineModule(truffleModule, "Interop");
defineModule(truffleModule, "Debug");
defineModule(truffleModule, "Primitive");
defineModule(truffleModule, "Digest");

// Rubinius

@@ -442,6 +444,7 @@ private void addCoreMethods() {
coreMethodNodeManager.addCoreMethodNodes(PosixNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(RubiniusTypeNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(ThreadBacktraceLocationNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(DigestNodesFactory.getFactories());
}

private void initializeGlobalVariables() {
55 changes: 24 additions & 31 deletions truffle/src/main/ruby/core/truffle/cext/require.rb
Original file line number Diff line number Diff line change
@@ -6,47 +6,40 @@
# GNU General Public License version 2
# GNU Lesser General Public License version 2.1

module Kernel
if Truffle::CExt.supported?

if Truffle::CExt.supported?
# Monkey patch #require, similar to how RubyGems does, in order to load
# C extensions.

# Monkey patch #require, similar to how RubyGems does, in order to load
# C extensions.
def require(name)
# We're getting quite hacky here. A lot of C extensions are required
# using the format foo/foo, so we need to guess that the real name is
# foo from that.

alias_method :truffle_cext_original_require, :require

def require(name)
# We're getting quite hacky here. A lot of C extensions are required
# using the format foo/foo, so we need to guess that the real name is
# foo from that.

if name =~ /(.+?)\/\1/
cext_name = $1
else
cext_name = name
end
if name =~ /(.+?)\/\1/
cext_name = $1
else
cext_name = name
end

# Look in each $JRUBY_TRUFFLE_CEXT_PATH directory for
# cext_name/ext/cext_name/extconf.rb
# Look in each $JRUBY_TRUFFLE_CEXT_PATH directory for
# cext_name/ext/cext_name/extconf.rb

if ENV.include? 'JRUBY_TRUFFLE_CEXT_PATH'
cext_path = ENV['JRUBY_TRUFFLE_CEXT_PATH'].split(':')
else
cext_path = [Dir.pwd]
end
if ENV.include? 'JRUBY_TRUFFLE_CEXT_PATH'
cext_path = ENV['JRUBY_TRUFFLE_CEXT_PATH'].split(':')
else
cext_path = [Dir.pwd]
end

cext_path.each do |dir|
extconf = File.join(dir, cext_name, 'ext', cext_name, 'extconf.rb')
cext_path.each do |dir|
extconf = File.join(dir, cext_name, 'ext', cext_name, 'extconf.rb')

if File.exist? extconf
return Truffle::CExt::load_extconf(extconf)
end
if File.exist? extconf
return Truffle::CExt::load_extconf(extconf)
end

truffle_cext_original_require name
end
module_function :require

Kernel.require name
end

end