Skip to content

Instantly share code, notes, and snippets.

@nanki
Created May 8, 2012 10:58
Show Gist options
  • Save nanki/2634245 to your computer and use it in GitHub Desktop.
Save nanki/2634245 to your computer and use it in GitHub Desktop.
require 'ffi'
module FFI::MRuby
extend ::FFI::Library
ffi_lib 'ritevm'
enum :mrb_vtype, [
:FALSE, :FREE, :TRUE, :FIXNUM,
:SYMBOL, :UNDEF, :FLOAT, :OBJECT,
:CLASS, :MODULE, :ICLASS, :SCLASS,
:PROC, :ARRAY, :HASH, :STRING,
:RANGE, :REGEX, :STRUCT, :EXCEPTION,
:MATCH, :FILE, :ENV, :DATA,
:THREAD, :THREADGRP, :MAXDEFINE
]
typedef :int32_t, :mrb_int
typedef :pointer, :mrb_state
typedef :intptr_t, :mrb_sym
class ValueU < FFI::Union
layout(
:p, :pointer,
:f, :double,
:i, :mrb_int,
:sym, :mrb_sym
)
end
class MrbValue < FFI::Struct
layout(
:value, ValueU,
:tt, :mrb_vtype
)
end
module MrbValueConverter
def self.native_type
MrbValue.by_value
end
def self.from_native(value, ctx=nil)
return value unless ctx
case value[:tt]
when :FALSE
if value[:value][:i] == 0
nil
else
false
end
when :TRUE
true
when :FIXNUM
value[:value][:i]
when :FLOAT
value[:value][:f]
when :SYMBOL
mrb_sym2name(ctx, value[:value][:sym]).intern
when :STRING
str = mrb_string_value_ptr(ctx, value)
str.read_string_length mrb_str_capacity(value)
when :ARRAY
[]
else
p [value[:value][:p], value[:tt]]
end
end
def self.to_native(obj, ctx=nil)
return obj if MrbValue === obj
args =
case obj
when TrueClass
[:i, 1, :TRUE]
when FalseClass
[:i, 1, :FALSE]
when NilClass
[:p, 0, :FALSE]
when Fixnum
if obj < 2<<31
[:i, obj, :FIXNUM]
else
[:f, obj.to_f, :FLOAT]
end
when Integer
[:f, obj.to_f, :FLOAT]
when Float
[:f, obj, :FLOAT]
when Symbol
[:sym, mrb_intern(ctx, obj.to_s), :SYMBOL]
when String
return mrb_str_new(ctx, obj, obj.length)
when Array
a = mrb_ary_new_capa(ctx, obj.size)
obj.each_with_index do |v, i|
a.mrb_ary_set(ctx, a, i, to_native(v, ctx))
end
return a
end
raise "unknown type #{obj.class}" unless args
build_value *args
end
private
def self.build_value(u, v, t)
value = MrbValue.new
value[:value][u] = v
value[:tt] = t
value
end
end
typedef FFI::Type::Mapped.new(MrbValueConverter), :mrb_value
attach_function :mrb_open, [], :mrb_state
attach_function :mrb_close, [:mrb_state], :void
attach_function :mrb_intern, [:mrb_state, :string], :mrb_sym
attach_function :mrb_sym2name, [:mrb_state, :mrb_sym], :string
attach_function :mrb_str_new, [:mrb_state, :string, :size_t], :mrb_value
attach_function :mrb_str_new_cstr, [:mrb_state, :string], :mrb_value
attach_function :mrb_string_value_ptr, [:mrb_state, :mrb_value], :pointer
attach_function :mrb_str_capacity, [:mrb_value], :size_t
attach_function :mrb_ary_new, [:mrb_state], :mrb_value
attach_function :mrb_ary_new_capa, [:mrb_state, :size_t], :mrb_value
attach_function :mrb_ary_set, [:mrb_state, :mrb_value, :mrb_int, :mrb_value], :void
attach_function :mrb_funcall, [:mrb_state, :mrb_value, :string, :int, :varargs], :mrb_value
attach_function :mrb_funcall_argv, [:mrb_state, :mrb_value, :string, :int, :pointer], :mrb_value
attach_function :mrb_p, [:mrb_state, :mrb_value], :mrb_value
attach_function :mrb_obj_id, [:mrb_value], :int
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment