Skip to content

Commit

Permalink
Add FFI::Union
Browse files Browse the repository at this point in the history
  • Loading branch information
dbussink committed Nov 25, 2012
1 parent 49fd6db commit 51b52ed
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 11 deletions.
24 changes: 24 additions & 0 deletions kernel/platform/ffi.rb
Expand Up @@ -50,6 +50,8 @@ def type_size(type)
return type_size(find_type(type)) return type_size(find_type(type))
when Rubinius::NativeFunction when Rubinius::NativeFunction
return type_size(TYPE_PTR) return type_size(TYPE_PTR)
when FFI::Enum
return type_size(TYPE_ENUM)
end end


raise PrimitiveFailure, "FFI.type_size primitive failed: #{type}" raise PrimitiveFailure, "FFI.type_size primitive failed: #{type}"
Expand Down Expand Up @@ -198,6 +200,28 @@ def initialize(struct)
end end


Struct = StructByValue Struct = StructByValue

OBJECT = TYPE_OBJECT
CHAR = TYPE_CHAR
UCHAR = TYPE_UCHAR
BOOL = TYPE_BOOL
SHORT = TYPE_SHORT
USHORT = TYPE_USHORT
INT = TYPE_INT
UINT = TYPE_UINT
LONG = TYPE_LONG
ULONG = TYPE_ULONG
LL = TYPE_LL
ULL = TYPE_ULL
FLOAT = TYPE_FLOAT
DOUBLE = TYPE_DOUBLE
PTR = TYPE_PTR
VOID = TYPE_VOID
STRING = TYPE_STRING
STATE = TYPE_STATE
STRPTR = TYPE_STRPTR
CHARARR = TYPE_CHARARR
ENUM = TYPE_ENUM
end end
end end


Expand Down
2 changes: 1 addition & 1 deletion kernel/platform/library.rb
Expand Up @@ -261,7 +261,7 @@ def find_type(name)
@typedefs ||= Rubinius::LookupTable.new @typedefs ||= Rubinius::LookupTable.new


if name.kind_of? Rubinius::NativeFunction or name.kind_of? FFI::Enum if name.kind_of? Rubinius::NativeFunction or name.kind_of? FFI::Enum
return name return name
end end


if type = @typedefs[name] if type = @typedefs[name]
Expand Down
1 change: 1 addition & 0 deletions kernel/platform/load_order18.txt
Expand Up @@ -8,3 +8,4 @@ file.rbc
math.rbc math.rbc
posix.rbc posix.rbc
struct.rbc struct.rbc
union.rbc
1 change: 1 addition & 0 deletions kernel/platform/load_order19.txt
Expand Up @@ -9,3 +9,4 @@ math.rbc
math19.rbc math19.rbc
posix.rbc posix.rbc
struct.rbc struct.rbc
union.rbc
1 change: 1 addition & 0 deletions kernel/platform/load_order20.txt
Expand Up @@ -9,3 +9,4 @@ math.rbc
math19.rbc math19.rbc
posix.rbc posix.rbc
struct.rbc struct.rbc
union.rbc
36 changes: 26 additions & 10 deletions kernel/platform/struct.rb
Expand Up @@ -6,6 +6,8 @@ module FFI


class Struct class Struct


@offset_zero = false

class InlineArray class InlineArray
def initialize(type, ptr) def initialize(type, ptr)
@pointer = ptr @pointer = ptr
Expand Down Expand Up @@ -124,7 +126,7 @@ def self.layout(*spec)


type = FFI::Type::Array.new(type_code, ary_size, klass) type = FFI::Type::Array.new(type_code, ary_size, klass)
element_size = type_size * ary_size element_size = type_size * ary_size
elsif f.kind_of?(Class) and f < FFI::Struct elsif f.kind_of?(Class) and (f < FFI::Struct || f < FFI::Union)
type = FFI::Type::StructByValue.new(f) type = FFI::Type::StructByValue.new(f)
element_size = type_size = f.size element_size = type_size = f.size
else else
Expand All @@ -143,12 +145,16 @@ def self.layout(*spec)
if offset.kind_of?(Fixnum) if offset.kind_of?(Fixnum)
i += 3 i += 3
else else
offset = @size if self < FFI::Union
offset = 0
else
offset = @size


mod = offset % type_size mod = offset % type_size
unless mod == 0 unless mod == 0
# we need to align it. # we need to align it.
offset += (type_size - mod) offset += (type_size - mod)
end
end end


i += 2 i += 2
Expand Down Expand Up @@ -194,13 +200,23 @@ def size
end end


def self.offset_of(name) def self.offset_of(name)
offset, type = @cspec[name] @layout[name].first
return offset
end end


def offset_of(name) def offset_of(name)
offset, type = @cspec[name] @cspec[name].first
return offset end

def self.offsets
members.map do |member|
[member, @layout[member].first]
end
end

def offsets
members.map do |member|
[member, @cspec[member].first]
end
end end


def self.members def self.members
Expand Down
10 changes: 10 additions & 0 deletions kernel/platform/union.rb
@@ -0,0 +1,10 @@
# -*- encoding: us-ascii -*-

module FFI
##
# Represents a C union as ruby class.

class Union < Struct
end
end

1 change: 1 addition & 0 deletions vm/builtin/nativefunction.cpp
Expand Up @@ -123,6 +123,7 @@ namespace rubinius {


case RBX_FFI_TYPE_INT: case RBX_FFI_TYPE_INT:
case RBX_FFI_TYPE_UINT: case RBX_FFI_TYPE_UINT:
case RBX_FFI_TYPE_ENUM:
return sizeof(int); return sizeof(int);


case RBX_FFI_TYPE_LONG: case RBX_FFI_TYPE_LONG:
Expand Down
1 change: 1 addition & 0 deletions vm/ffi.cpp
Expand Up @@ -53,5 +53,6 @@ namespace rubinius {
mod->set_const(state, "TYPE_STATE", Fixnum::from(RBX_FFI_TYPE_STATE)); mod->set_const(state, "TYPE_STATE", Fixnum::from(RBX_FFI_TYPE_STATE));
mod->set_const(state, "TYPE_STRPTR", Fixnum::from(RBX_FFI_TYPE_STRPTR)); mod->set_const(state, "TYPE_STRPTR", Fixnum::from(RBX_FFI_TYPE_STRPTR));
mod->set_const(state, "TYPE_CHARARR", Fixnum::from(RBX_FFI_TYPE_CHARARR)); mod->set_const(state, "TYPE_CHARARR", Fixnum::from(RBX_FFI_TYPE_CHARARR));
mod->set_const(state, "TYPE_ENUM", Fixnum::from(RBX_FFI_TYPE_ENUM));
} }
}; };

0 comments on commit 51b52ed

Please sign in to comment.