From 40eaa2095ed282d7b9247ca0116e7cc06360b2b9 Mon Sep 17 00:00:00 2001 From: Ghabry Date: Tue, 9 May 2017 20:02:48 +0200 Subject: [PATCH 1/3] Add MRI 1.8 Support --- binding-mri/binding-mri.cpp | 12 ++- binding-mri/binding-util.cpp | 74 ++++++++++++++++++ binding-mri/binding-util.h | 116 ++++++++++++++++++++++++++++- binding-mri/filesystem-binding.cpp | 12 ++- 4 files changed, 210 insertions(+), 4 deletions(-) diff --git a/binding-mri/binding-mri.cpp b/binding-mri/binding-mri.cpp index 1c0057b..b9be9bc 100644 --- a/binding-mri/binding-mri.cpp +++ b/binding-mri/binding-mri.cpp @@ -32,7 +32,9 @@ #include "boost-hash.h" #include +#if RUBY_API_VERSION_MAJOR > 1 #include +#endif #include #include @@ -204,7 +206,7 @@ RB_METHOD(mriP) RB_METHOD(mkxpDataDirectory) { RB_UNUSED_PARAM; - + const std::string &path = shState->config().customDataPath; const char *s = path.empty() ? "." : path.c_str(); @@ -580,9 +582,15 @@ static void mriBindingExecute() * stdio streams on some platforms (eg. Windows) */ int argc = 0; char **argv = 0; - ruby_sysinit(&argc, &argv); +#if RUBY_API_VERSION_MAJOR == 1 + ruby_init(); + //ruby_options(argc, argv); +#else + ruby_sysinit(&argc, &argv); ruby_setup(); +#endif + rb_enc_set_default_external(rb_enc_from_encoding(rb_utf8_encoding())); Config &conf = shState->rtData().config; diff --git a/binding-mri/binding-util.cpp b/binding-mri/binding-util.cpp index e73d999..ffbb742 100644 --- a/binding-mri/binding-util.cpp +++ b/binding-mri/binding-util.cpp @@ -90,6 +90,9 @@ void raiseRbExc(const Exception &exc) void raiseDisposedAccess(VALUE self) { +#if RUBY_API_VERSION_MAJOR == 1 +// FIXME: raiseDisposedAccess not implemented +#else const char *klassName = RTYPEDDATA_TYPE(self)->wrap_struct_name; char buf[32]; @@ -97,6 +100,7 @@ raiseDisposedAccess(VALUE self) buf[0] = tolower(buf[0]); rb_raise(getRbData()->exc[RGSS], "disposed %s", buf); +#endif } int @@ -319,3 +323,73 @@ rb_get_args(int argc, VALUE *argv, const char *format, ...) return argI; } + +#if RUBY_API_VERSION_MAJOR == 1 +// Functions providing Ruby 1.8 compatibililty +VALUE rb_sprintf(const char* fmt, ...) { + va_list args; + va_start(args, fmt); + char buf[4096]; + int const result = vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + + return rb_str_new2(buf); +} + +VALUE rb_data_typed_object_alloc(VALUE klass, void *datap, const rb_data_type_t * rbType) { + return rb_data_object_alloc(klass, 0, rbType->function.dmark, rbType->function.dfree); +} + +void *rb_check_typeddata(VALUE v, const rb_data_type_t *) { +// FIXME: rb_check_typeddata not implemented + 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); +} + +rb_encoding *rb_utf8_encoding(void) { + return NULL; +} + +void rb_enc_set_default_external(VALUE encoding) { + // no-op, assuming UTF-8 +} + +VALUE rb_enc_from_encoding(rb_encoding *enc) { + return Qnil; +} + +VALUE rb_str_catf(VALUE, const char*, ...) { + return Qnil; +} + +VALUE rb_errinfo(void) { + return ruby_errinfo; +} + +int rb_typeddata_is_kind_of(VALUE, const rb_data_type_t *) { + return 1; +} + +VALUE rb_file_open_str(VALUE filename, const char* mode) { + return rb_file_open(RB_OBJ_STRING(filename), mode); +} + +VALUE rb_enc_associate_index(VALUE, int) { + return Qnil; +} + +int rb_utf8_encindex(void) { + return 0; +} + +VALUE rb_hash_lookup2(VALUE, VALUE, VALUE) { + return Qnil; +} +#endif diff --git a/binding-mri/binding-util.h b/binding-mri/binding-util.h index 1b758be..e3f35d9 100644 --- a/binding-mri/binding-util.h +++ b/binding-mri/binding-util.h @@ -23,9 +23,124 @@ #define BINDING_UTIL_H #include +#include #include "exception.h" +// Ruby 1.8 and Ruby 2.x use different version macros +#ifndef RUBY_API_VERSION_MAJOR +#define RUBY_API_VERSION_MAJOR RUBY_VERSION_MAJOR +#endif + +#if RUBY_API_VERSION_MAJOR == 1 +// Functions and macros providing Ruby 1.8 compatibililty +#define FLONUM_P(x) 0 + +#define RB_FLOAT_TYPE_P(obj) (FLONUM_P(obj) || (!SPECIAL_CONST_P(obj) && BUILTIN_TYPE(obj) == T_FLOAT)) + +#define RB_TYPE_P(obj, type) ( \ + ((type) == T_FIXNUM) ? FIXNUM_P(obj) : \ + ((type) == T_TRUE) ? ((obj) == Qtrue) : \ + ((type) == T_FALSE) ? ((obj) == Qfalse) : \ + ((type) == T_NIL) ? ((obj) == Qnil) : \ + ((type) == T_UNDEF) ? ((obj) == Qundef) : \ + ((type) == T_SYMBOL) ? SYMBOL_P(obj) : \ + ((type) == T_FLOAT) ? RB_FLOAT_TYPE_P(obj) : \ + (!SPECIAL_CONST_P(obj) && BUILTIN_TYPE(obj) == (type))) + +#define RUBY_T_ARRAY T_ARRAY +#define RUBY_T_STRING T_STRING +#define RUBY_T_FLOAT T_FLOAT +#define RUBY_T_FIXNUM T_FIXNUM +#define RUBY_T_TRUE T_TRUE +#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) +#define RUBY_NEVER_FREE ((RUBY_DATA_FUNC)0) +#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 + +#define ENCODING_INLINE_MAX 127 +#define ENCODING_SHIFT (FL_USHIFT+10) +#define ENCODING_MASK (((VALUE)ENCODING_INLINE_MAX)<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)) + +#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; +} rb_data_type_t; + +VALUE rb_sprintf(const char* fmt, ...); + +VALUE rb_data_typed_object_alloc(VALUE klass, void *datap, const rb_data_type_t *); + +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*); + +rb_encoding *rb_utf8_encoding(void); + +void rb_enc_set_default_external(VALUE encoding); + +VALUE rb_enc_from_encoding(rb_encoding *enc); + +VALUE rb_str_catf(VALUE, const char*, ...); + +VALUE rb_errinfo(void); + +int rb_typeddata_is_kind_of(VALUE, const rb_data_type_t *); + +VALUE rb_file_open_str(VALUE, const char*); + +VALUE rb_enc_associate_index(VALUE, int); + +int rb_utf8_encindex(void); + +VALUE rb_hash_lookup2(VALUE, VALUE, VALUE); + +#endif + enum RbException { RGSS = 0, @@ -66,7 +181,6 @@ raiseRbExc(const Exception &exc); extern rb_data_type_t Klass##Type /* 2.1 has added a new field (flags) to rb_data_type_t */ -#include #if RUBY_API_VERSION_MAJOR >= 2 && RUBY_API_VERSION_MINOR >= 1 /* TODO: can mkxp use RUBY_TYPED_FREE_IMMEDIATELY here? */ #define DEF_TYPE_FLAGS 0 diff --git a/binding-mri/filesystem-binding.cpp b/binding-mri/filesystem-binding.cpp index 4bc5e03..c12e268 100644 --- a/binding-mri/filesystem-binding.cpp +++ b/binding-mri/filesystem-binding.cpp @@ -25,7 +25,9 @@ #include "filesystem.h" #include "util.h" +#if RUBY_API_VERSION_MAJOR > 1 #include "ruby/encoding.h" +#endif #include "ruby/intern.h" static void @@ -130,7 +132,6 @@ kernelLoadDataInt(const char *filename, bool rubyExc) VALUE port = fileIntForPath(filename, rubyExc); VALUE marsh = rb_const_get(rb_cObject, rb_intern("Marshal")); - // FIXME need to catch exceptions here with begin rescue VALUE result = rb_funcall2(marsh, rb_intern("load"), 1, &port); @@ -195,14 +196,21 @@ RB_METHOD(_marshalLoad) rb_get_args(argc, argv, "o|o", &port, &proc RB_ARG_END); VALUE utf8Proc; + // FIXME: Not implemented for Ruby 1.8 +#if RUBY_API_VERSION_MAJOR > 1 if (NIL_P(proc)) utf8Proc = rb_proc_new(RUBY_METHOD_FUNC(stringForceUTF8), Qnil); else utf8Proc = rb_proc_new(RUBY_METHOD_FUNC(customProc), proc); +#endif VALUE marsh = rb_const_get(rb_cObject, rb_intern("Marshal")); +#if RUBY_API_VERSION_MAJOR > 1 VALUE v[] = { port, utf8Proc }; +#else + VALUE v[] = { port, proc }; +#endif return rb_funcall2(marsh, rb_intern("_mkxp_load_alias"), ARRAY_SIZE(v), v); } @@ -214,6 +222,8 @@ fileIntBindingInit() _rb_define_method(klass, "read", fileIntRead); _rb_define_method(klass, "getbyte", fileIntGetByte); + // Used by Ruby 1.8 Marshaller + _rb_define_method(klass, "getc", fileIntGetByte); _rb_define_method(klass, "binmode", fileIntBinmode); _rb_define_method(klass, "close", fileIntClose); -- 2.43.0 From 5064e19421e29060b75bf7394a2e5e1be6c649bd Mon Sep 17 00:00:00 2001 From: Ghabry Date: Fri, 12 May 2017 12:32:38 +0200 Subject: [PATCH 2/3] 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 | 42 +++++++++++++++++------------- binding-mri/filesystem-binding.cpp | 6 ++--- 4 files changed, 35 insertions(+), 28 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 e3f35d9..b6bf9f1 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,16 +87,16 @@ #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) @@ -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 { @@ -181,7 +188,7 @@ raiseRbExc(const Exception &exc); extern rb_data_type_t Klass##Type /* 2.1 has added a new field (flags) to rb_data_type_t */ -#if RUBY_API_VERSION_MAJOR >= 2 && RUBY_API_VERSION_MINOR >= 1 +#if RUBY_API_VERSION_MAJOR > 1 && RUBY_API_VERSION_MINOR > 0 /* TODO: can mkxp use RUBY_TYPED_FREE_IMMEDIATELY here? */ #define DEF_TYPE_FLAGS 0 #else @@ -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 }; -- 2.43.0 From 7ef1213b37ac92e25a4c87fecefb1394bf1a7dc1 Mon Sep 17 00:00:00 2001 From: Ghabry Date: Mon, 22 May 2017 19:22:14 +0200 Subject: [PATCH 3/3] Ruby 1.8: Style improvements. Implement rb_str_catf & rb_hash_lookup2. --- binding-mri/binding-mri.cpp | 1 - binding-mri/binding-util.cpp | 106 +++++++++++++++++++++-------- binding-mri/filesystem-binding.cpp | 1 + 3 files changed, 78 insertions(+), 30 deletions(-) diff --git a/binding-mri/binding-mri.cpp b/binding-mri/binding-mri.cpp index a6d9685..a4f0960 100644 --- a/binding-mri/binding-mri.cpp +++ b/binding-mri/binding-mri.cpp @@ -585,7 +585,6 @@ static void mriBindingExecute() #if RUBY_API_VERSION_MAJOR == 1 ruby_init(); - //ruby_options(argc, argv); #else ruby_sysinit(&argc, &argv); ruby_setup(); diff --git a/binding-mri/binding-util.cpp b/binding-mri/binding-util.cpp index 6203ec8..1bc2b49 100644 --- a/binding-mri/binding-util.cpp +++ b/binding-mri/binding-util.cpp @@ -91,16 +91,16 @@ void raiseDisposedAccess(VALUE self) { #ifdef RUBY_LEGACY_VERSION -// FIXME: raiseDisposedAccess not implemented + const char *klassName = rb_class2name(self); #else const char *klassName = RTYPEDDATA_TYPE(self)->wrap_struct_name; +#endif char buf[32]; strncpy(buf, klassName, sizeof(buf)); buf[0] = tolower(buf[0]); rb_raise(getRbData()->exc[RGSS], "disposed %s", buf); -#endif } int @@ -325,72 +325,120 @@ rb_get_args(int argc, VALUE *argv, const char *format, ...) } #if RUBY_API_VERSION_MAJOR == 1 -NORETURN(void rb_error_arity(int, int, int)) { +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; - va_start(args, fmt); +/* +Functions providing Ruby 1.8 compatibililty. +All encoding related functions return dummy values because mkxp only uses them +to retrieve the UTF-8 encoding. +*/ +VALUE rb_sprintf_vararg(const char* fmt, va_list args) { char buf[4096]; - int const result = vsnprintf(buf, sizeof(buf), fmt, args); - va_end(args); + int result = vsnprintf(buf, sizeof(buf), fmt, args); + + if (result < 0) { + buf[0] = '\0'; + } return rb_str_new2(buf); } -VALUE rb_data_typed_object_alloc(VALUE klass, void *datap, const rb_data_type_t * rbType) { - return rb_data_object_alloc(klass, 0, rbType->function.dmark, rbType->function.dfree); +VALUE rb_sprintf(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + VALUE val = rb_sprintf_vararg(fmt, args); + va_end(args); + + return val; } -void *rb_check_typeddata(VALUE v, const rb_data_type_t *) { -// FIXME: rb_check_typeddata not implemented - return RTYPEDDATA_DATA(v); +VALUE rb_data_typed_object_alloc(VALUE klass, void *datap, const rb_data_type_t *rbType) +{ + return rb_data_object_alloc(klass, 0, rbType->function.dmark, rbType->function.dfree); } -VALUE rb_enc_str_new(const char* ch, long len, rb_encoding*) { +void *rb_check_typeddata(VALUE value, const rb_data_type_t* typed) +{ +// FIXME: Won't work because rb_typeddata_is_kind_of is not implemented + if (!rb_typeddata_is_kind_of(value, typed)) { + rb_raise(getRbData()->exc[RGSS], + "wrong data type %s (expected %s)", rb_class2name(value), typed->wrap_struct_name + ); + } + + return RTYPEDDATA_DATA(value); +} + +VALUE rb_enc_str_new(const char* ch, long len, rb_encoding*) +{ + // Encoding is ignored return rb_str_new(ch, len); } -rb_encoding *rb_utf8_encoding(void) { +rb_encoding *rb_utf8_encoding(void) +{ + // not relevant return NULL; } -void rb_enc_set_default_external(VALUE encoding) { - // no-op, assuming UTF-8 +void rb_enc_set_default_external(VALUE) +{ + // not relevant } -VALUE rb_enc_from_encoding(rb_encoding *enc) { +VALUE rb_enc_from_encoding(rb_encoding*) +{ + // not relevant return Qnil; } -VALUE rb_str_catf(VALUE, const char*, ...) { - return Qnil; +VALUE rb_str_catf(VALUE value, const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + VALUE second = rb_sprintf_vararg(fmt, args); + va_end(args); + + return rb_str_concat(value, second); } -VALUE rb_errinfo(void) { +VALUE rb_errinfo(void) +{ return ruby_errinfo; } -int rb_typeddata_is_kind_of(VALUE, const rb_data_type_t *) { +int rb_typeddata_is_kind_of(VALUE value, const rb_data_type_t* typed) +{ +// FIXME: rb_typeddata_is_kind_of not implemented return 1; } -VALUE rb_file_open_str(VALUE filename, const char* mode) { +VALUE rb_file_open_str(VALUE filename, const char* mode) +{ return rb_file_open(RB_OBJ_STRING(filename), mode); } -VALUE rb_enc_associate_index(VALUE, int) { +VALUE rb_enc_associate_index(VALUE, int) +{ + // not relevant return Qnil; } -int rb_utf8_encindex(void) { +int rb_utf8_encindex(void) +{ + // not relevant return 0; } -VALUE rb_hash_lookup2(VALUE, VALUE, VALUE) { - return Qnil; +VALUE rb_hash_lookup2(VALUE hash, VALUE key, VALUE def) +{ + VALUE v = rb_hash_lookup(hash, key); + return (v == Qnil) ? def : v; } #endif // RUBY_API_VERSION_MINOR == 8 -#endif // RUBY_API_VERSION_MAJOR == 1 \ No newline at end of file +#endif // RUBY_API_VERSION_MAJOR == 1 diff --git a/binding-mri/filesystem-binding.cpp b/binding-mri/filesystem-binding.cpp index 9a92c52..512ce4f 100644 --- a/binding-mri/filesystem-binding.cpp +++ b/binding-mri/filesystem-binding.cpp @@ -132,6 +132,7 @@ kernelLoadDataInt(const char *filename, bool rubyExc) VALUE port = fileIntForPath(filename, rubyExc); VALUE marsh = rb_const_get(rb_cObject, rb_intern("Marshal")); + // FIXME need to catch exceptions here with begin rescue VALUE result = rb_funcall2(marsh, rb_intern("load"), 1, &port); -- 2.43.0