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

Commits on Apr 24, 2015

  1. Copy the full SHA
    a82a006 View commit details
  2. Copy the full SHA
    d715d31 View commit details
  3. Copy the full SHA
    ce4af59 View commit details
  4. Copy the full SHA
    0248e3b View commit details
  5. Copy the full SHA
    229ed76 View commit details
  6. Copy the full SHA
    081148a View commit details
33 changes: 33 additions & 0 deletions lib/ruby/truffle/shims/fcntl.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# 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 Fcntl
F_DUPFD = Rubinius::Config['rbx.platform.fcntl.F_DUPFD']
F_GETFD = Rubinius::Config['rbx.platform.fcntl.F_GETFD']
F_GETLK = Rubinius::Config['rbx.platform.fcntl.F_GETLK']
F_SETFD = Rubinius::Config['rbx.platform.fcntl.F_SETFD']
F_GETFL = Rubinius::Config['rbx.platform.fcntl.F_GETFL']
F_SETFL = Rubinius::Config['rbx.platform.fcntl.F_SETFL']
F_SETLK = Rubinius::Config['rbx.platform.fcntl.F_SETLK']
F_SETLKW = Rubinius::Config['rbx.platform.fcntl.F_SETLKW']
FD_CLOEXEC = Rubinius::Config['rbx.platform.fcntl.FD_CLOEXEC']
F_RDLCK = Rubinius::Config['rbx.platform.fcntl.F_RDLCK']
F_UNLCK = Rubinius::Config['rbx.platform.fcntl.F_UNLCK']
F_WRLCK = Rubinius::Config['rbx.platform.fcntl.F_WRLCK']
O_CREAT = Rubinius::Config['rbx.platform.file.O_CREAT']
O_EXCL = Rubinius::Config['rbx.platform.file.O_EXCL']
O_NOCTTY = Rubinius::Config['rbx.platform.file.O_NOCTTY']
O_TRUNC = Rubinius::Config['rbx.platform.file.O_TRUNC']
O_APPEND = Rubinius::Config['rbx.platform.file.O_APPEND']
O_NONBLOCK = Rubinius::Config['rbx.platform.file.O_NONBLOCK']
O_NDELAY = Rubinius::Config['rbx.platform.file.O_NDELAY']
O_RDONLY = Rubinius::Config['rbx.platform.file.O_RDONLY']
O_RDWR = Rubinius::Config['rbx.platform.file.O_RDWR']
O_WRONLY = Rubinius::Config['rbx.platform.file.O_WRONLY']
O_ACCMODE = Rubinius::Config['rbx.platform.file.O_ACCMODE']
end
28 changes: 28 additions & 0 deletions test/truffle/simple-server.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
# code is released under a tri EPL/GPL/LGPL license. You can use it,
# redistribute it and/or modify it under the terms of the:
#
# Eclipse Public License version 1.0
# GNU General Public License version 2
# GNU Lesser General Public License version 2.1

require 'socket'

server = TCPServer.new('localhost', 8080)

loop do
socket = server.accept

begin
request = socket.gets

socket.print "HTTP/1.1 200 OK\r\n" +
"Content-Type: text/plain\r\n" +
"Content-Length: #{request.bytesize}\r\n" +
"Connection: close\r\n\r\n"
socket.print request
socket.print "\n"
ensure
socket.close
end
end
Original file line number Diff line number Diff line change
@@ -78,6 +78,42 @@ public MaterializedFrame visitFrame(FrameInstance frameInstance) {

}

@CoreMethod(names = "source_of_caller", onSingleton = true)
public abstract static class SourceOfCallerNode extends CoreMethodNode {

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

public SourceOfCallerNode(SourceOfCallerNode prev) {
super(prev);
}

@Specialization
public RubyString sourceOfCaller() {
notDesignedForCompilation();

final Memo<Integer> frameCount = new Memo<>(0);

final String source = Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor<String>() {

@Override
public String visitFrame(FrameInstance frameInstance) {
if (frameCount.get() == 1) {
return frameInstance.getCallNode().getEncapsulatingSourceSection().getSource().getName();
} else {
frameCount.set(frameCount.get() + 1);
return null;
}
}

});

return getContext().makeString(source);
}

}

@CoreMethod(names = "gc_count", onSingleton = true)
public abstract static class GCCountNode extends CoreMethodNode {

Original file line number Diff line number Diff line change
@@ -207,4 +207,100 @@ protected boolean isSigned(boolean signed) {

}

@RubiniusPrimitive(name = "pointer_set_autorelease")
public static abstract class PointerSetAutoreleasePrimitiveNode extends ReadAddressPrimitiveNode {

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

public PointerSetAutoreleasePrimitiveNode(PointerSetAutoreleasePrimitiveNode prev) {
super(prev);
}

@Specialization
public boolean setAutorelease(RubyBasicObject pointer, boolean autorelease) {
// TODO CS 24-April-2015 let memory leak
return autorelease;
}

}

@RubiniusPrimitive(name = "pointer_set_at_offset")
public static abstract class PointerSetAtOffsetPrimitiveNode extends ReadAddressPrimitiveNode {

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

public PointerSetAtOffsetPrimitiveNode(PointerSetAtOffsetPrimitiveNode prev) {
super(prev);
}

@Specialization
public int setAtOffset(RubyBasicObject pointer, int offset, Object type, int value) {
UnsafeHolder.U.putInt(getAddress(pointer), value);
return value;
}

}

@RubiniusPrimitive(name = "pointer_read_pointer")
public static abstract class PointerReadPointerPrimitiveNode extends ReadAddressPrimitiveNode {

@Child private WriteHeadObjectFieldNode writeAddressNode;
@Child private ReadHeadObjectFieldNode readAddressNode;

public PointerReadPointerPrimitiveNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
writeAddressNode = new WriteHeadObjectFieldNode(ADDRESS_IDENTIFIER);
readAddressNode = new ReadHeadObjectFieldNode(PointerPrimitiveNodes.ADDRESS_IDENTIFIER);
}

public PointerReadPointerPrimitiveNode(PointerReadPointerPrimitiveNode prev) {
super(prev);
writeAddressNode = prev.writeAddressNode;
readAddressNode = prev.readAddressNode;
}

@Specialization
public RubyBasicObject readPointer(RubyBasicObject pointer) {
final RubyBasicObject readPointer = new RubyBasicObject(pointer.getLogicalClass());
writeAddress(readPointer, UnsafeHolder.U.getLong(getAddress(pointer)));
return pointer;
}

public long writeAddress(RubyBasicObject pointer, long address) {
writeAddressNode.execute(pointer, address);
return address;
}

public long getAddress(RubyBasicObject pointer) {
try {
return readAddressNode.executeLong(pointer);
} catch (UnexpectedResultException e) {
throw new UnsupportedOperationException();
}
}

}

@RubiniusPrimitive(name = "pointer_address")
public static abstract class PointerAddressPrimitiveNode extends ReadAddressPrimitiveNode {

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

public PointerAddressPrimitiveNode(PointerAddressPrimitiveNode prev) {
super(prev);
}

@Specialization
public long address(RubyBasicObject pointer) {
return getAddress(pointer);
}

}

}
Original file line number Diff line number Diff line change
@@ -14,14 +14,14 @@
import jnr.posix.FileStat;
import org.jruby.truffle.runtime.RubyContext;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.*;

public class RubiniusConfiguration {

private static final int SIZE_OF_SHORT = 2;
private static final int SIZE_OF_INT = 4;
private static final int SIZE_OF_LONG = 8;
private static final int SIZE_OF_POINTER = 8;

private final RubyContext context;

@@ -71,16 +71,132 @@ public RubiniusConfiguration(RubyContext context) {
config("rbx.platform.typedef.time_t", "long");

config("rbx.platform.timeval.sizeof", 2 * SIZE_OF_LONG);
config("rbx.platform.timeval.tv_sec.offset", 0 * SIZE_OF_LONG);
config("rbx.platform.timeval.tv_sec.offset", 0);
config("rbx.platform.timeval.tv_sec.size", SIZE_OF_LONG);
config("rbx.platform.timeval.tv_sec.type", "time_t");
config("rbx.platform.timeval.tv_usec.offset", 1 * SIZE_OF_LONG);
config("rbx.platform.timeval.tv_usec.offset", SIZE_OF_LONG);
config("rbx.platform.timeval.tv_usec.size", SIZE_OF_LONG);
config("rbx.platform.timeval.tv_usec.type", "time_t");

/*
* struct addrinfo {
* int ai_flags;
* int ai_family;
* int ai_socktype;
* int ai_protocol;
* socklen_t ai_addrlen;
* struct sockaddr *ai_addr;
* char *ai_canonname;
* struct addrinfo *ai_next;
* };
*/

config("rbx.platform.addrinfo.sizeof", 4 * SIZE_OF_INT + 4 * SIZE_OF_LONG);

int addrInfoOffset = 0;

for (String field : Arrays.asList("ai_flags", "ai_family", "ai_socktype", "ai_protocol")) {
config("rbx.platform.addrinfo." + field + ".offset", addrInfoOffset);
config("rbx.platform.addrinfo." + field + ".size", SIZE_OF_INT);
config("rbx.platform.addrinfo." + field + ".type", "int");
addrInfoOffset += SIZE_OF_INT;
}

config("rbx.platform.addrinfo.ai_addrlen.offset", addrInfoOffset);
config("rbx.platform.addrinfo.ai_addrlen.size", SIZE_OF_LONG);
config("rbx.platform.addrinfo.ai_addrlen.type", "long");
addrInfoOffset += SIZE_OF_LONG;

for (String field : Arrays.asList("ai_addr", "ai_canonname", "ai_next")) {
config("rbx.platform.addrinfo." + field + ".offset", addrInfoOffset);
config("rbx.platform.addrinfo." + field + ".size", SIZE_OF_POINTER);
config("rbx.platform.addrinfo." + field + ".type", "pointer");
addrInfoOffset += SIZE_OF_LONG;
}

/*
* struct linger {
* int l_onoff;
* int l_linger;
* };
*/

config("rbx.platform.linger.sizeof", 2 * SIZE_OF_INT);

int lingerOffset = 0;

for (String field : Arrays.asList("l_onoff", "l_linger")) {
config("rbx.platform.linger." + field + ".offset", lingerOffset);
config("rbx.platform.linger." + field + ".size", SIZE_OF_INT);
config("rbx.platform.linger." + field + ".type", "int");
lingerOffset += SIZE_OF_INT;
}

/*
* struct sockaddr_in {
* short sin_family;
* unsigned short sin_port;
* struct in_addr sin_addr;
* char sin_zero[8];
* };
*
* struct in_addr {
* unsigned long s_addr;
* };
*/

config("rbx.platform.sockaddr_in.sizeof", 2 * SIZE_OF_SHORT + SIZE_OF_LONG + 8);

config("rbx.platform.sockaddr_in.sin_family.offset", 0);
config("rbx.platform.sockaddr_in.sin_family.size", SIZE_OF_SHORT);
config("rbx.platform.sockaddr_in.sin_family.type", "short");

config("rbx.platform.sockaddr_in.sin_port.offset", SIZE_OF_SHORT);
config("rbx.platform.sockaddr_in.sin_port.size", SIZE_OF_SHORT);
config("rbx.platform.sockaddr_in.sin_port.type", "ushort");

config("rbx.platform.sockaddr_in.sin_addr.offset", 2 * SIZE_OF_SHORT);
config("rbx.platform.sockaddr_in.sin_addr.size", SIZE_OF_LONG);
config("rbx.platform.sockaddr_in.sin_addr.type", "ulong");

config("rbx.platform.sockaddr_in.sin_zero.offset", 2 * SIZE_OF_SHORT + SIZE_OF_LONG);
config("rbx.platform.sockaddr_in.sin_zero.size", 8);
config("rbx.platform.sockaddr_in.sin_zero.type", "char");

/*
* struct servent {
* char *s_name;
* char **s_aliases;
* int s_port;
* char *s_proto;
* };
*/

config("rbx.platform.servent.sizeof", 3 * SIZE_OF_POINTER + SIZE_OF_INT);

config("rbx.platform.servent.s_name.offset", 0);
config("rbx.platform.servent.s_name.size", SIZE_OF_POINTER);
config("rbx.platform.servent.s_name.type", "pointer");

config("rbx.platform.servent.s_aliases.offset", SIZE_OF_POINTER);
config("rbx.platform.servent.s_aliases.size", SIZE_OF_POINTER);
config("rbx.platform.servent.s_aliases.type", "pointer");

config("rbx.platform.servent.s_port.offset", 2 * SIZE_OF_POINTER);
config("rbx.platform.servent.s_port.size", SIZE_OF_INT);
config("rbx.platform.servent.s_port.type", "int");

config("rbx.platform.servent.s_proto.offset", 2 * SIZE_OF_POINTER + SIZE_OF_INT);
config("rbx.platform.servent.s_proto.size", SIZE_OF_POINTER);
config("rbx.platform.servent.s_proto.type", "pointer");

config("rbx.platform.io.SEEK_SET", 0);
config("rbx.platform.io.SEEK_CUR", 1);
config("rbx.platform.io.SEEK_END", 2);

config("rbx.platform.socket.AI_PASSIVE", context.makeString("1"));
config("rbx.platform.socket.AF_UNSPEC", context.makeString("0"));
config("rbx.platform.socket.SOCK_STREAM", context.makeString("1"));
}

private void config(String key, String value) {
1 change: 1 addition & 0 deletions truffle/src/main/ruby/core.rb
Original file line number Diff line number Diff line change
@@ -229,6 +229,7 @@
require_relative 'core/string'
require_relative 'core/thread'
require_relative 'core/unbound_method'
require_relative 'core/library'

require_relative 'core/shims'

78 changes: 78 additions & 0 deletions truffle/src/main/ruby/core/library.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Copyright (c) 2014, 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
#
# Contains code adapted from platform/library.rb in Rubinius
#
# Copyright (c) 2007-2014, Evan Phoenix and contributors
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Rubinius nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# This is part of the Rubinius FFI implementation that links to native
# libraries. We simply hook up a method which we already provide, so it only
# works for libraries we are expecting.

module Rubinius::FFI::Library

def attach_function(name, a2, a3, a4=nil, a5=nil)
# Argument handling from Rubinius

if a4 && (a2.kind_of?(String) || a2.kind_of?(Symbol))
cname = a2.to_s
args = a3
ret = a4
else
cname = name.to_s
args = a2
ret = a3
end

mname = name.to_sym

# But we've already implemented the actual methods elsewhere

caller = Truffle::Primitive.source_of_caller

if caller.end_with? 'ruby/truffle/rubysl/rubysl-socket/lib/rubysl/socket.rb'
if Rubinius::FFI::Platform::Socket.respond_to? mname
define_method mname, Rubinius::FFI::Platform::Socket.method(mname)
module_function mname
return
end
end

# Fallback

define_method mname do |*|
raise "FFI::Library method #{name} with caller #{caller} not implemented"
end
module_function mname
end

end