From 2c9c3c19861f043380736921d462cfcc4c866b39 Mon Sep 17 00:00:00 2001 From: Ghabry Date: Fri, 12 May 2017 12:32:38 +0200 Subject: [PATCH] Add MRI 1.9 Support. Unfortunately crashes on startup with "[BUG] object allocation during garbage collection phase" --- binding-mri/binding-mri.cpp | 2 +- binding-mri/binding-util.cpp | 13 ++++--- binding-mri/binding-util.h | 60 ++++++++++++++++-------------- binding-mri/filesystem-binding.cpp | 6 +-- 4 files changed, 44 insertions(+), 37 deletions(-) diff --git a/binding-mri/binding-mri.cpp b/binding-mri/binding-mri.cpp index b9be9bc..a6d9685 100644 --- a/binding-mri/binding-mri.cpp +++ b/binding-mri/binding-mri.cpp @@ -32,7 +32,7 @@ #include "boost-hash.h" #include -#if RUBY_API_VERSION_MAJOR > 1 +#ifndef RUBY_LEGACY_VERSION #include #endif diff --git a/binding-mri/binding-util.cpp b/binding-mri/binding-util.cpp index ffbb742..6203ec8 100644 --- a/binding-mri/binding-util.cpp +++ b/binding-mri/binding-util.cpp @@ -90,7 +90,7 @@ void raiseRbExc(const Exception &exc) void raiseDisposedAccess(VALUE self) { -#if RUBY_API_VERSION_MAJOR == 1 +#ifdef RUBY_LEGACY_VERSION // FIXME: raiseDisposedAccess not implemented #else const char *klassName = RTYPEDDATA_TYPE(self)->wrap_struct_name; @@ -325,6 +325,10 @@ rb_get_args(int argc, VALUE *argv, const char *format, ...) } #if RUBY_API_VERSION_MAJOR == 1 +NORETURN(void rb_error_arity(int, int, int)) { + assert(false); +} +#if RUBY_API_VERSION_MINOR == 8 // Functions providing Ruby 1.8 compatibililty VALUE rb_sprintf(const char* fmt, ...) { va_list args; @@ -345,10 +349,6 @@ void *rb_check_typeddata(VALUE v, const rb_data_type_t *) { return RTYPEDDATA_DATA(v); } -NORETURN(void rb_error_arity(int, int, int)) { - assert(false); -} - VALUE rb_enc_str_new(const char* ch, long len, rb_encoding*) { return rb_str_new(ch, len); } @@ -392,4 +392,5 @@ int rb_utf8_encindex(void) { VALUE rb_hash_lookup2(VALUE, VALUE, VALUE) { return Qnil; } -#endif +#endif // RUBY_API_VERSION_MINOR == 8 +#endif // RUBY_API_VERSION_MAJOR == 1 \ No newline at end of file diff --git a/binding-mri/binding-util.h b/binding-mri/binding-util.h index 416e135..6cc34c7 100644 --- a/binding-mri/binding-util.h +++ b/binding-mri/binding-util.h @@ -27,12 +27,27 @@ #include "exception.h" -// Ruby 1.8 and Ruby 2.x use different version macros +// Ruby 1.8 and Ruby 1.9+ use different version macros #ifndef RUBY_API_VERSION_MAJOR #define RUBY_API_VERSION_MAJOR RUBY_VERSION_MAJOR #endif +#ifndef RUBY_API_VERSION_MINOR +#define RUBY_API_VERSION_MINOR RUBY_VERSION_MINOR +#endif + #if RUBY_API_VERSION_MAJOR == 1 +#define PRIsVALUE "s" +#define RB_OBJ_CLASSNAME(obj) rb_obj_classname(obj) +#define RB_OBJ_STRING(obj) StringValueCStr(obj) + +NORETURN(void rb_error_arity(int, int, int)); + +#define OBJ_INIT_COPY(obj, orig) \ + ((obj) != (orig) && (rb_obj_init_copy((obj), (orig)), 1)) +#if RUBY_API_VERSION_MINOR == 8 +// Makes version checks easier +#define RUBY_LEGACY_VERSION // Functions and macros providing Ruby 1.8 compatibililty #define FLONUM_P(x) 0 @@ -56,9 +71,6 @@ #define RUBY_T_FALSE T_FALSE #define RUBY_T_NIL T_NIL -#define OBJ_INIT_COPY(obj, orig) \ - ((obj) != (orig) && (rb_obj_init_copy((obj), (orig)), 1)) - #define rb_str_new_cstr rb_str_new2 #define RUBY_DEFAULT_FREE ((RUBY_DATA_FUNC)-1) @@ -66,10 +78,6 @@ #define RUBY_TYPED_DEFAULT_FREE RUBY_DEFAULT_FREE #define RUBY_TYPED_NEVER_FREE RUBY_NEVER_FREE -#define PRIsVALUE "s" -#define RB_OBJ_CLASSNAME(obj) rb_obj_classname(obj) -#define RB_OBJ_STRING(obj) StringValueCStr(obj) - #define RTYPEDDATA_DATA DATA_PTR #define RFLOAT_VALUE(d) RFLOAT(d)->value @@ -79,30 +87,30 @@ #define ENCODING_MASK (((VALUE)ENCODING_INLINE_MAX)<flags &= ~ENCODING_MASK;\ - RBASIC(obj)->flags |= (VALUE)(i) << ENCODING_SHIFT;\ + RBASIC(obj)->flags &= ~ENCODING_MASK;\ + RBASIC(obj)->flags |= (VALUE)(i) << ENCODING_SHIFT;\ } while (0) #define ENCODING_SET(obj,i) rb_enc_set_index((obj), (i)) #define ENCODING_GET_INLINED(obj) (int)((RBASIC(obj)->flags & ENCODING_MASK)>>ENCODING_SHIFT) #define ENCODING_GET(obj) \ - (ENCODING_GET_INLINED(obj) != ENCODING_INLINE_MAX ? \ - ENCODING_GET_INLINED(obj) : \ - rb_enc_get_index(obj)) + (ENCODING_GET_INLINED(obj) != ENCODING_INLINE_MAX ? \ + ENCODING_GET_INLINED(obj) : \ + rb_enc_get_index(obj)) #define ENCODING_IS_ASCII8BIT(obj) (ENCODING_GET_INLINED(obj) == 0) typedef struct { - const char *wrap_struct_name; - struct { - void (*dmark)(void*); - void (*dfree)(void*); - size_t (*dsize)(const void *); - void *reserved[2]; - } function; - const char *parent; - void *data; - VALUE flags; + const char *wrap_struct_name; + struct { + void (*dmark)(void*); + void (*dfree)(void*); + size_t (*dsize)(const void *); + void *reserved[2]; + } function; + const char *parent; + void *data; + VALUE flags; } rb_data_type_t; VALUE rb_sprintf(const char* fmt, ...); @@ -113,8 +121,6 @@ void *rb_check_typeddata(VALUE, const rb_data_type_t *); #define Check_TypedStruct(v,t) rb_check_typeddata((VALUE)(v),(t)) -NORETURN(void rb_error_arity(int, int, int)); - typedef void rb_encoding; VALUE rb_enc_str_new(const char*, long, rb_encoding*); @@ -139,7 +145,8 @@ int rb_utf8_encindex(void); VALUE rb_hash_lookup2(VALUE, VALUE, VALUE); -#endif +#endif // RUBY_API_VERSION_MINOR == 8 +#endif // RUBY_API_VERSION_MAJOR == 1 enum RbException { @@ -497,5 +504,4 @@ rb_check_argc(int actual, int expected) _rb_define_method(klass, prop_name_s "=", Klass##Set##PropName); \ } - #endif // BINDING_UTIL_H diff --git a/binding-mri/filesystem-binding.cpp b/binding-mri/filesystem-binding.cpp index c12e268..9a92c52 100644 --- a/binding-mri/filesystem-binding.cpp +++ b/binding-mri/filesystem-binding.cpp @@ -25,7 +25,7 @@ #include "filesystem.h" #include "util.h" -#if RUBY_API_VERSION_MAJOR > 1 +#ifndef RUBY_LEGACY_VERSION #include "ruby/encoding.h" #endif #include "ruby/intern.h" @@ -197,7 +197,7 @@ RB_METHOD(_marshalLoad) VALUE utf8Proc; // FIXME: Not implemented for Ruby 1.8 -#if RUBY_API_VERSION_MAJOR > 1 +#ifndef RUBY_LEGACY_VERSION if (NIL_P(proc)) utf8Proc = rb_proc_new(RUBY_METHOD_FUNC(stringForceUTF8), Qnil); else @@ -206,7 +206,7 @@ RB_METHOD(_marshalLoad) VALUE marsh = rb_const_get(rb_cObject, rb_intern("Marshal")); -#if RUBY_API_VERSION_MAJOR > 1 +#ifndef RUBY_LEGACY_VERSION VALUE v[] = { port, utf8Proc }; #else VALUE v[] = { port, proc };