Created
September 30, 2017 16:44
-
-
Save bjfish/534f99282ed785a61752a566a244a359 to your computer and use it in GitHub Desktop.
C ext header patching tool
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Copyright (c) 2017 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 | |
# Run with ruby tool/update-mri-cext.rb | |
require 'fileutils' | |
TRUFFLERUBY_DIR = File.expand_path('../..', File.realpath(__FILE__)) | |
TRUFFLERUBY_CEXT_LIB_DIR = File.join(TRUFFLERUBY_DIR, 'lib', 'cext') | |
RUBY_DIR = File.join(File.dirname(TRUFFLERUBY_DIR),'ruby') | |
RUBY_INCLUDE_DIR = File.join(RUBY_DIR, 'include') | |
raise "Cannot find ruby dir:`#{RUBY_DIR}`" unless File.exist?(RUBY_DIR) | |
Dir.glob("#{TRUFFLERUBY_CEXT_LIB_DIR}/**/*").each { |f| | |
FileUtils.rm_rf(f) unless (f.include?('preprocess.rb') || f.include?('truffle.h') || f.include?('internal.h') || f.end_with?('lib/cext/ruby') || f.include?('ruby/config.h') || f.end_with?('lib/cext/include') || f.include?('include/ruby.h') || f.end_with?('lib/cext/truffle') || f.end_with?('truffle/ruby.h') ) | |
} | |
FileUtils.cp_r "#{RUBY_INCLUDE_DIR}/.", TRUFFLERUBY_CEXT_LIB_DIR | |
FileUtils::Verbose.cp_r "#{RUBY_DIR}/ccan/.", File.join(TRUFFLERUBY_CEXT_LIB_DIR, 'ccan') | |
Dir.glob(File.join(TRUFFLERUBY_CEXT_LIB_DIR, 'ccan','licenses/**')).each { |f| | |
FileUtils.rm_rf(f) | |
} | |
APPEND = <<-EOF | |
\\0 | |
#define rb_sprintf(format, ...) \ | |
(VALUE) truffle_invoke(RUBY_CEXT, "rb_sprintf", rb_str_new_cstr(format), ##__VA_ARGS__) | |
NORETURN(VALUE rb_f_notimplement(int args_count, const VALUE *args, VALUE object)); | |
// Non-standard | |
NORETURN(void rb_tr_error(const char *message)); | |
void rb_tr_log_warning(const char *message); | |
#define rb_tr_debug(args...) truffle_invoke(RUBY_CEXT, "rb_tr_debug", args) | |
long rb_tr_obj_id(VALUE object); | |
void rb_tr_hidden_variable_set(VALUE object, const char *name, VALUE value); | |
VALUE rb_tr_hidden_variable_get(VALUE object, const char *name); | |
// Handles | |
void *rb_tr_handle_for_managed(VALUE managed); | |
void *rb_tr_handle_for_managed_leaking(VALUE managed); | |
VALUE rb_tr_managed_from_handle_or_null(void *handle); | |
VALUE rb_tr_managed_from_handle(void *handle); | |
void rb_tr_release_handle(void *handle); | |
bool rb_tr_obj_taintable_p(VALUE object); | |
bool rb_tr_obj_tainted_p(VALUE object); | |
void rb_tr_obj_infect(VALUE a, VALUE b); | |
#define Qfalse_int_const 0 | |
#define Qtrue_int_const 2 | |
#define Qnil_int_const 4 | |
int rb_tr_to_int_const(VALUE value); | |
int rb_tr_readable(int mode); | |
int rb_tr_writable(int mode); | |
typedef void *(*gvl_call)(void *); | |
#define RETURN_ENUMERATOR_NAME(obj, meth, argc, argv) do { \ | |
if (!rb_block_given_p()) \ | |
return rb_enumeratorize((obj), (meth), (argc), (argv)); \ | |
} while (0) | |
// Exceptions | |
#define rb_raise(EXCEPTION, FORMAT, ...) \ | |
rb_exc_raise(rb_exc_new_str(EXCEPTION, (VALUE) truffle_invoke(rb_mKernel, "sprintf", rb_str_new_cstr(FORMAT), ##__VA_ARGS__))) | |
// Utilities | |
#define rb_warn(FORMAT, ...) do { \ | |
if (truffle_invoke_b(RUBY_CEXT, "warn?")) { \ | |
truffle_invoke(rb_mKernel, "warn", (VALUE) truffle_invoke(rb_mKernel, "sprintf", rb_str_new_cstr(FORMAT), ##__VA_ARGS__)); \ | |
} \ | |
} while (0); | |
#define rb_warning(FORMAT, ...) do { \ | |
if (truffle_invoke_b(RUBY_CEXT, "warning?")) { \ | |
truffle_invoke(rb_mKernel, "warn", (VALUE) truffle_invoke(rb_mKernel, "sprintf", rb_str_new_cstr(FORMAT), ##__VA_ARGS__)); \ | |
} \ | |
} while (0); | |
MUST_INLINE int rb_tr_scan_args(int argc, VALUE *argv, const char *format, VALUE *v1, VALUE *v2, VALUE *v3, VALUE *v4, VALUE *v5, VALUE *v6, VALUE *v7, VALUE *v8, VALUE *v9, VALUE *v10); | |
#define rb_tr_scan_args_1(ARGC, ARGV, FORMAT, V1) rb_tr_scan_args(ARGC, ARGV, FORMAT, V1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) | |
#define rb_tr_scan_args_2(ARGC, ARGV, FORMAT, V1, V2) rb_tr_scan_args(ARGC, ARGV, FORMAT, V1, V2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) | |
#define rb_tr_scan_args_3(ARGC, ARGV, FORMAT, V1, V2, V3) rb_tr_scan_args(ARGC, ARGV, FORMAT, V1, V2, V3, NULL, NULL, NULL, NULL, NULL, NULL, NULL) | |
#define rb_tr_scan_args_4(ARGC, ARGV, FORMAT, V1, V2, V3, V4) rb_tr_scan_args(ARGC, ARGV, FORMAT, V1, V2, V3, V4, NULL, NULL, NULL, NULL, NULL, NULL) | |
#define rb_tr_scan_args_5(ARGC, ARGV, FORMAT, V1, V2, V3, V4, V5) rb_tr_scan_args(ARGC, ARGV, FORMAT, V1, V2, V3, V4, V5, NULL, NULL, NULL, NULL, NULL) | |
#define rb_tr_scan_args_6(ARGC, ARGV, FORMAT, V1, V2, V3, V4, V5, V6) rb_tr_scan_args(ARGC, ARGV, FORMAT, V1, V2, V3, V4, V5, V6, NULL, NULL, NULL, NULL) | |
#define rb_tr_scan_args_7(ARGC, ARGV, FORMAT, V1, V2, V3, V4, V5, V6, V7) rb_tr_scan_args(ARGC, ARGV, FORMAT, V1, V2, V3, V4, V5, V6, V7, NULL, NULL, NULL) | |
#define rb_tr_scan_args_8(ARGC, ARGV, FORMAT, V1, V2, V3, V4, V5, V6, V7, V8) rb_tr_scan_args(ARGC, ARGV, FORMAT, V1, V2, V3, V4, V5, V6, V7, V8, NULL, NULL) | |
#define rb_tr_scan_args_9(ARGC, ARGV, FORMAT, V1, V2, V3, V4, V5, V6, V7, V8, V9) rb_tr_scan_args(ARGC, ARGV, FORMAT, V1, V2, V3, V4, V5, V6, V7, V8, V9, NULL) | |
#define rb_tr_scan_args_10(ARGC, ARGV, FORMAT, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10) rb_tr_scan_args(ARGC, ARGV, FORMAT, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10) | |
#define SCAN_ARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, NAME, ...) NAME | |
#define rb_scan_args(ARGC, ARGV, FORMAT, ...) SCAN_ARGS_IMPL(__VA_ARGS__, rb_tr_scan_args_10, rb_tr_scan_args_9, rb_tr_scan_args_8, rb_tr_scan_args_7, rb_tr_scan_args_6, rb_tr_scan_args_5, rb_tr_scan_args_4, rb_tr_scan_args_3, rb_tr_scan_args_2, rb_tr_scan_args_1)(ARGC, ARGV, FORMAT, __VA_ARGS__) | |
// Calls | |
#define rb_funcall(object, ...) truffle_invoke(RUBY_CEXT, "rb_funcall", (void *) object, __VA_ARGS__) | |
// Additional non-standard | |
VALUE CHR2FIX(char ch); | |
unsigned int FIX2UINT(VALUE value); | |
int RB_NIL_P(VALUE value); | |
VALUE rb_java_class_of(VALUE val); | |
VALUE rb_java_to_string(VALUE val); | |
VALUE rb_equal_opt(VALUE a, VALUE b); | |
int rb_encdb_alias(const char *alias, const char *orig); | |
VALUE rb_ivar_lookup(VALUE object, const char *name, VALUE default_value); | |
// Overrides | |
#ifdef memcpy | |
#undef memcpy | |
#endif | |
#define memcpy truffle_managed_memcpy | |
// Inline implementations | |
MUST_INLINE int rb_nativethread_lock_initialize(rb_nativethread_lock_t *lock) { | |
*lock = truffle_invoke(RUBY_CEXT, "rb_nativethread_lock_initialize"); | |
return 0; | |
} | |
MUST_INLINE int rb_nativethread_lock_destroy(rb_nativethread_lock_t *lock) { | |
*lock = NULL; | |
return 0; | |
} | |
MUST_INLINE int rb_nativethread_lock_lock(rb_nativethread_lock_t *lock) { | |
truffle_invoke(*lock, "lock"); | |
return 0; | |
} | |
MUST_INLINE int rb_nativethread_lock_unlock(rb_nativethread_lock_t *lock) { | |
truffle_invoke(*lock, "unlock"); | |
return 0; | |
} | |
MUST_INLINE int rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp) { | |
if (rb_obj_is_kind_of(range, rb_cRange)) { | |
*begp = (VALUE) truffle_invoke(range, "begin"); | |
*endp = (VALUE) truffle_invoke(range, "end"); | |
*exclp = (int) truffle_invoke_b(range, "exclude_end?"); | |
} | |
else { | |
if (!truffle_invoke_b(range, "respond_to?", rb_intern("begin"))) return (int)Qfalse; | |
if (!truffle_invoke_b(range, "respond_to?", rb_intern("end"))) return (int)Qfalse; | |
*begp = truffle_invoke(range, "begin"); | |
*endp = truffle_invoke(range, "end"); | |
*exclp = (int) RTEST(truffle_invoke(range, "exclude_end?")); | |
} | |
return (int) Qtrue; | |
} | |
MUST_INLINE VALUE rb_string_value(VALUE *value_pointer) { | |
VALUE value = *value_pointer; | |
if (!RB_TYPE_P(value, T_STRING)) { | |
value = rb_str_to_str(value); | |
*value_pointer = value; | |
} | |
return value; | |
} | |
MUST_INLINE char *rb_string_value_ptr(VALUE *value_pointer) { | |
VALUE string = rb_string_value(value_pointer); | |
return RSTRING_PTR(string); | |
} | |
MUST_INLINE char *rb_string_value_cstr(VALUE *value_pointer) { | |
VALUE string = rb_string_value(value_pointer); | |
truffle_invoke(RUBY_CEXT, "rb_string_value_cstr_check", string); | |
return RSTRING_PTR(string); | |
} | |
MUST_INLINE int rb_tr_scan_args(int argc, VALUE *argv, const char *format, VALUE *v1, VALUE *v2, VALUE *v3, VALUE *v4, VALUE *v5, VALUE *v6, VALUE *v7, VALUE *v8, VALUE *v9, VALUE *v10) { | |
// Parse the format string | |
// TODO CS 7-Feb-17 maybe we could inline cache this part? | |
const char *formatp = format; | |
int pre = 0; | |
int optional = 0; | |
bool rest; | |
int post = 0; | |
bool kwargs; | |
bool block; | |
// TODO CS 27-Feb-17 can LLVM constant-fold through isdigit? | |
if (isdigit(*formatp)) { | |
pre = *formatp - '0'; | |
formatp++; | |
if (isdigit(*formatp)) { | |
optional = *formatp - '0'; | |
formatp++; | |
} | |
} | |
if (*formatp == '*') { | |
rest = true; | |
formatp++; | |
} else { | |
rest = false; | |
} | |
if (isdigit(*formatp)) { | |
post = *formatp - '0'; | |
formatp++; | |
} | |
if (*formatp == ':') { | |
kwargs = true; | |
formatp++; | |
} else { | |
kwargs = false; | |
} | |
if (*formatp == '&') { | |
block = true; | |
formatp++; | |
} else { | |
block = false; | |
} | |
if (*formatp != '\0') { | |
rb_raise(rb_eArgError, "bad rb_scan_args format"); | |
} | |
// Check we have enough arguments | |
if (pre + post > argc) { | |
rb_raise(rb_eArgError, "not enough arguments for required"); | |
} | |
// Read arguments | |
int argn = 0; | |
int valuen = 1; // We've numbered the v parameters from 1 | |
bool taken_rest = false; | |
bool taken_block = false; | |
bool taken_kwargs = false; | |
bool erased_kwargs = false; | |
bool found_kwargs = false; | |
if (rest && kwargs && !truffle_invoke_b(RUBY_CEXT, "test_kwargs", argv[argc - 1], Qfalse)) { | |
kwargs = false; | |
erased_kwargs = true; | |
} | |
int trailing = post; | |
if (kwargs) { | |
trailing++; | |
} | |
while (true) { | |
// Get the next argument | |
VALUE arg; | |
if (pre > 0 || optional > 0) { | |
if (argn < argc - trailing) { | |
arg = argv[argn]; | |
argn++; | |
} else { | |
arg = Qnil; | |
} | |
if (pre > 0) { | |
pre--; | |
} else { | |
optional--; | |
} | |
} else if (rest && !taken_rest) { | |
arg = rb_ary_new(); | |
while (argn < argc - trailing) { | |
rb_ary_push(arg, argv[argn]); | |
argn++; | |
} | |
taken_rest = true; | |
} else if (post > 0) { | |
arg = argv[argn]; | |
argn++; | |
post--; | |
} else if (kwargs && !taken_kwargs) { | |
if (argn < argc) { | |
arg = argv[argn]; | |
truffle_invoke(RUBY_CEXT, "test_kwargs", argv[argn], Qtrue); | |
argn++; | |
found_kwargs = true; | |
} else { | |
arg = Qnil; | |
} | |
taken_kwargs = true; | |
} else if (erased_kwargs && !taken_kwargs) { | |
arg = Qnil; | |
taken_kwargs = true; | |
} else if (block && !taken_block) { | |
if (rb_block_given_p()) { | |
arg = rb_block_proc(); | |
} else { | |
arg = Qnil; | |
} | |
taken_block = true; | |
} else { | |
break; | |
} | |
// Put the argument into the current value pointer | |
// Don't assign the correct v to a temporary VALUE* and then assign arg to it - this doesn't optimise well | |
switch (valuen) { | |
case 1: *v1 = arg; break; | |
case 2: *v2 = arg; break; | |
case 3: *v3 = arg; break; | |
case 4: *v4 = arg; break; | |
case 5: *v5 = arg; break; | |
case 6: *v6 = arg; break; | |
case 7: *v7 = arg; break; | |
case 8: *v8 = arg; break; | |
case 9: *v9 = arg; break; | |
case 10: *v10 = arg; break; | |
} | |
valuen++; | |
} | |
if (found_kwargs) { | |
return argc - 1; | |
} else { | |
return argc; | |
} | |
} | |
EOF | |
RB_TYPE_P = <<-EOF | |
bool RB_TYPE_P(VALUE value, int type); | |
EOF | |
AFTER_CONFIG = <<-EOF | |
\\0 | |
#include <truffle.h> | |
#include <ctype.h> // isdigit | |
// Support | |
#define RUBY_CEXT (void *)truffle_import_cached("ruby_cext") | |
#define MUST_INLINE __attribute__((always_inline)) inline | |
#include <ruby/thread_native.h> | |
// Helpers | |
#ifndef offsetof | |
#define offsetof(p_type,field) ((size_t)&(((p_type *)0)->field)) | |
#endif | |
EOF | |
SPECIAL_CONST_P = <<-EOF | |
VALUE rb_special_const_p(VALUE object); | |
#define RB_SPECIAL_CONST_P(x) rb_special_const_p(x) | |
EOF | |
RB_ENCODING = <<-EOF | |
typedef struct { | |
char *name; | |
} rb_encoding; | |
EOF | |
STR_WITH_ENC = <<-EOF | |
VALUE rb_external_str_with_enc(VALUE string, rb_encoding *eenc); | |
rb_encoding *get_encoding(VALUE string); | |
#define STR_ENC_GET(string) get_encoding(string) | |
\\0 | |
EOF | |
RDATA = <<-EOF | |
\\0 | |
struct RData *RDATA(VALUE value); | |
EOF | |
RB_IO = <<-EOF | |
typedef struct rb_io_t { | |
int mode; | |
int fd; | |
} rb_io_t; | |
EOF | |
GENERATED_CONSTANTS = <<-EOF | |
// START from tool/generate-cext-constants.rb | |
VALUE rb_tr_get_undef(void); | |
VALUE rb_tr_get_true(void); | |
VALUE rb_tr_get_false(void); | |
VALUE rb_tr_get_nil(void); | |
VALUE rb_tr_get_Array(void); | |
VALUE rb_tr_get_Bignum(void); | |
VALUE rb_tr_get_Class(void); | |
VALUE rb_tr_get_Comparable(void); | |
VALUE rb_tr_get_Data(void); | |
VALUE rb_tr_get_Encoding(void); | |
VALUE rb_tr_get_Enumerable(void); | |
VALUE rb_tr_get_FalseClass(void); | |
VALUE rb_tr_get_File(void); | |
VALUE rb_tr_get_Fixnum(void); | |
VALUE rb_tr_get_Float(void); | |
VALUE rb_tr_get_Hash(void); | |
VALUE rb_tr_get_Integer(void); | |
VALUE rb_tr_get_IO(void); | |
VALUE rb_tr_get_Kernel(void); | |
VALUE rb_tr_get_Match(void); | |
VALUE rb_tr_get_Module(void); | |
VALUE rb_tr_get_NilClass(void); | |
VALUE rb_tr_get_Numeric(void); | |
VALUE rb_tr_get_Object(void); | |
VALUE rb_tr_get_Range(void); | |
VALUE rb_tr_get_Regexp(void); | |
VALUE rb_tr_get_String(void); | |
VALUE rb_tr_get_Struct(void); | |
VALUE rb_tr_get_Symbol(void); | |
VALUE rb_tr_get_Time(void); | |
VALUE rb_tr_get_Thread(void); | |
VALUE rb_tr_get_TrueClass(void); | |
VALUE rb_tr_get_Proc(void); | |
VALUE rb_tr_get_Method(void); | |
VALUE rb_tr_get_Dir(void); | |
VALUE rb_tr_get_ArgError(void); | |
VALUE rb_tr_get_EOFError(void); | |
VALUE rb_tr_get_Errno(void); | |
VALUE rb_tr_get_Exception(void); | |
VALUE rb_tr_get_FloatDomainError(void); | |
VALUE rb_tr_get_IndexError(void); | |
VALUE rb_tr_get_Interrupt(void); | |
VALUE rb_tr_get_IOError(void); | |
VALUE rb_tr_get_LoadError(void); | |
VALUE rb_tr_get_LocalJumpError(void); | |
VALUE rb_tr_get_MathDomainError(void); | |
VALUE rb_tr_get_EncCompatError(void); | |
VALUE rb_tr_get_NameError(void); | |
VALUE rb_tr_get_NoMemError(void); | |
VALUE rb_tr_get_NoMethodError(void); | |
VALUE rb_tr_get_NotImpError(void); | |
VALUE rb_tr_get_RangeError(void); | |
VALUE rb_tr_get_RegexpError(void); | |
VALUE rb_tr_get_RuntimeError(void); | |
VALUE rb_tr_get_ScriptError(void); | |
VALUE rb_tr_get_SecurityError(void); | |
VALUE rb_tr_get_Signal(void); | |
VALUE rb_tr_get_StandardError(void); | |
VALUE rb_tr_get_SyntaxError(void); | |
VALUE rb_tr_get_SystemCallError(void); | |
VALUE rb_tr_get_SystemExit(void); | |
VALUE rb_tr_get_SysStackError(void); | |
VALUE rb_tr_get_TypeError(void); | |
VALUE rb_tr_get_ThreadError(void); | |
VALUE rb_tr_get_WaitReadable(void); | |
VALUE rb_tr_get_WaitWritable(void); | |
VALUE rb_tr_get_ZeroDivError(void); | |
VALUE rb_tr_get_stdin(void); | |
VALUE rb_tr_get_stdout(void); | |
VALUE rb_tr_get_stderr(void); | |
VALUE rb_tr_get_output_fs(void); | |
VALUE rb_tr_get_rs(void); | |
VALUE rb_tr_get_output_rs(void); | |
VALUE rb_tr_get_default_rs(void); | |
#define Qundef rb_tr_get_undef() | |
#define Qtrue rb_tr_get_true() | |
#define Qfalse rb_tr_get_false() | |
#define Qnil rb_tr_get_nil() | |
#define rb_cArray rb_tr_get_Array() | |
#define rb_cBignum rb_tr_get_Bignum() | |
#define rb_cClass rb_tr_get_Class() | |
#define rb_mComparable rb_tr_get_Comparable() | |
#define rb_cData rb_tr_get_Data() | |
#define rb_cEncoding rb_tr_get_Encoding() | |
#define rb_mEnumerable rb_tr_get_Enumerable() | |
#define rb_cFalseClass rb_tr_get_FalseClass() | |
#define rb_cFile rb_tr_get_File() | |
#define rb_cFixnum rb_tr_get_Fixnum() | |
#define rb_cFloat rb_tr_get_Float() | |
#define rb_cHash rb_tr_get_Hash() | |
#define rb_cInteger rb_tr_get_Integer() | |
#define rb_cIO rb_tr_get_IO() | |
#define rb_mKernel rb_tr_get_Kernel() | |
#define rb_cMatch rb_tr_get_Match() | |
#define rb_cModule rb_tr_get_Module() | |
#define rb_cNilClass rb_tr_get_NilClass() | |
#define rb_cNumeric rb_tr_get_Numeric() | |
#define rb_cObject rb_tr_get_Object() | |
#define rb_cRange rb_tr_get_Range() | |
#define rb_cRegexp rb_tr_get_Regexp() | |
#define rb_cString rb_tr_get_String() | |
#define rb_cStruct rb_tr_get_Struct() | |
#define rb_cSymbol rb_tr_get_Symbol() | |
#define rb_cTime rb_tr_get_Time() | |
#define rb_cThread rb_tr_get_Thread() | |
#define rb_cTrueClass rb_tr_get_TrueClass() | |
#define rb_cProc rb_tr_get_Proc() | |
#define rb_cMethod rb_tr_get_Method() | |
#define rb_cDir rb_tr_get_Dir() | |
#define rb_eArgError rb_tr_get_ArgError() | |
#define rb_eEOFError rb_tr_get_EOFError() | |
#define rb_mErrno rb_tr_get_Errno() | |
#define rb_eException rb_tr_get_Exception() | |
#define rb_eFloatDomainError rb_tr_get_FloatDomainError() | |
#define rb_eIndexError rb_tr_get_IndexError() | |
#define rb_eInterrupt rb_tr_get_Interrupt() | |
#define rb_eIOError rb_tr_get_IOError() | |
#define rb_eLoadError rb_tr_get_LoadError() | |
#define rb_eLocalJumpError rb_tr_get_LocalJumpError() | |
#define rb_eMathDomainError rb_tr_get_MathDomainError() | |
#define rb_eEncCompatError rb_tr_get_EncCompatError() | |
#define rb_eNameError rb_tr_get_NameError() | |
#define rb_eNoMemError rb_tr_get_NoMemError() | |
#define rb_eNoMethodError rb_tr_get_NoMethodError() | |
#define rb_eNotImpError rb_tr_get_NotImpError() | |
#define rb_eRangeError rb_tr_get_RangeError() | |
#define rb_eRegexpError rb_tr_get_RegexpError() | |
#define rb_eRuntimeError rb_tr_get_RuntimeError() | |
#define rb_eScriptError rb_tr_get_ScriptError() | |
#define rb_eSecurityError rb_tr_get_SecurityError() | |
#define rb_eSignal rb_tr_get_Signal() | |
#define rb_eStandardError rb_tr_get_StandardError() | |
#define rb_eSyntaxError rb_tr_get_SyntaxError() | |
#define rb_eSystemCallError rb_tr_get_SystemCallError() | |
#define rb_eSystemExit rb_tr_get_SystemExit() | |
#define rb_eSysStackError rb_tr_get_SysStackError() | |
#define rb_eTypeError rb_tr_get_TypeError() | |
#define rb_eThreadError rb_tr_get_ThreadError() | |
#define rb_mWaitReadable rb_tr_get_WaitReadable() | |
#define rb_mWaitWritable rb_tr_get_WaitWritable() | |
#define rb_eZeroDivError rb_tr_get_ZeroDivError() | |
#define rb_stdin rb_tr_get_stdin() | |
#define rb_stdout rb_tr_get_stdout() | |
#define rb_stderr rb_tr_get_stderr() | |
#define rb_output_fs rb_tr_get_output_fs() | |
#define rb_rs rb_tr_get_rs() | |
#define rb_output_rs rb_tr_get_output_rs() | |
#define rb_default_rs rb_tr_get_default_rs() | |
// END from tool/generate-cext-constants.rb | |
EOF | |
RB_NATIVE_THREAD = <<-EOF | |
typedef void *rb_nativethread_id_t; | |
typedef void *rb_nativethread_lock_t; | |
EOF | |
DEFINE_VALUE = <<-EOF | |
typedef void *VALUE; | |
typedef long SIGNED_VALUE; | |
typedef VALUE ID; | |
EOF | |
RSTRING_LEN = <<-EOF | |
int rb_str_len(VALUE string); | |
#define RSTRING_LEN(str) (long)rb_str_len(str) | |
EOF | |
RSTRING_PTR = <<-EOF | |
#define RSTRING_PTR(str) RSTRING_PTR_IMPL(str) | |
char *RSTRING_PTR_IMPL(VALUE string); | |
EOF | |
ALLOC = <<-EOF | |
#define ruby_xmalloc malloc | |
#define ruby_xmalloc2(items, size) malloc((items)*(size)) | |
#define ruby_xcalloc calloc | |
#define ruby_xrealloc realloc | |
#define ruby_xfree free | |
#define ALLOC(type) ((type *)ruby_xmalloc(sizeof(type))) | |
#define ALLOC_N(type, n) ((type *)malloc(sizeof(type) * (n))) | |
#define ALLOCA_N(type, n) ((type *)alloca(sizeof(type) * (n))) | |
#define RB_ZALLOC_N(type, n) ((type *)ruby_xcalloc((n), sizeof(type))) | |
#define RB_ZALLOC(type) (RB_ZALLOC_N(type, 1)) | |
#define ZALLOC_N(type, n) RB_ZALLOC_N(type, n) | |
#define ZALLOC(type) RB_ZALLOC(type) | |
void *rb_alloc_tmp_buffer(VALUE *buffer_pointer, long length); | |
void rb_free_tmp_buffer(VALUE *buffer_pointer); | |
#define RB_ALLOCV(v, n) rb_alloc_tmp_buffer(&(v), (n)) | |
#define RB_ALLOCV_N(type, v, n) rb_alloc_tmp_buffer(&(v), (n) * sizeof(type)) | |
EOF | |
NUM2SHORT = <<-EOF | |
#define NUM2SHORT(x) rb_num2short(x) | |
#define NUM2USHORT(x) rb_num2ushort(x) | |
EOF | |
TAINT_FREEZE = <<-EOF | |
#define RB_OBJ_TAINTABLE(object) rb_tr_obj_taintable_p(object) | |
#define RB_OBJ_TAINTED_RAW(object) rb_tr_obj_tainted_p(object) | |
#define RB_OBJ_TAINTED(object) rb_tr_obj_tainted_p(object) | |
#define RB_OBJ_TAINT_RAW(object) rb_obj_taint(object) | |
#define RB_OBJ_TAINT(object) rb_obj_taint(object) | |
#define RB_OBJ_UNTRUSTED(object) rb_tr_obj_tainted_p(object) | |
#define RB_OBJ_UNTRUST(object) rb_obj_taint(object) | |
#define OBJ_TAINTABLE(object) rb_tr_obj_taintable_p(object) | |
#define OBJ_TAINTED_RAW(object) rb_tr_obj_tainted_p(object) | |
#define OBJ_TAINTED(object) rb_tr_obj_tainted_p(object) | |
#define OBJ_TAINT_RAW(object) rb_obj_taint(object) | |
#define OBJ_TAINT(object) rb_obj_taint(object) | |
#define OBJ_UNTRUSTED(object) rb_tr_obj_tainted_p(object) | |
#define OBJ_UNTRUST(object) rb_tr_obj_tainted_p(object) | |
#define RB_OBJ_INFECT_RAW(a, b) rb_tr_obj_infect(a, b) | |
#define RB_OBJ_INFECT(a, b) rb_tr_obj_infect(a, b) | |
#define OBJ_INFECT(a, b) rb_tr_obj_infect(a, b) | |
#define RB_OBJ_FROZEN_RAW(object) rb_obj_frozen_p(object) | |
#define RB_OBJ_FROZEN(object) rb_obj_frozen_p(object) | |
#define RB_OBJ_FREEZE_RAW(object) rb_obj_freeze(object) | |
#define RB_OBJ_FREEZE(object) rb_obj_freeze((VALUE)object) | |
#define OBJ_FROZEN_RAW(object) rb_obj_frozen_p(object) | |
#define OBJ_FROZEN(object) rb_obj_frozen_p(object) | |
#define OBJ_FREEZE_RAW(object) rb_obj_freeze(object) | |
#define OBJ_FREEZE(object) rb_obj_freeze(object) | |
EOF | |
RUBY_CODERANGE_TYPE = <<-EOF | |
enum ruby_coderange_type { | |
RUBY_ENC_CODERANGE_UNKNOWN = 0, | |
RUBY_ENC_CODERANGE_7BIT = 1, | |
RUBY_ENC_CODERANGE_VALID = 2, | |
RUBY_ENC_CODERANGE_BROKEN = 4 | |
}; | |
EOF | |
ECONV = <<-EOF | |
enum ruby_econv_flag_type { | |
/* flags for rb_econv_open */ | |
RUBY_ECONV_ERROR_HANDLER_MASK = 0x000000ff, | |
RUBY_ECONV_INVALID_MASK = 0x0000000f, | |
RUBY_ECONV_INVALID_REPLACE = 0x00000002, | |
RUBY_ECONV_UNDEF_MASK = 0x000000f0, | |
RUBY_ECONV_UNDEF_REPLACE = 0x00000020, | |
RUBY_ECONV_UNDEF_HEX_CHARREF = 0x00000030, | |
RUBY_ECONV_DECORATOR_MASK = 0x0000ff00, | |
RUBY_ECONV_NEWLINE_DECORATOR_MASK = 0x00003f00, | |
RUBY_ECONV_NEWLINE_DECORATOR_READ_MASK = 0x00000f00, | |
RUBY_ECONV_NEWLINE_DECORATOR_WRITE_MASK = 0x00003000, | |
RUBY_ECONV_UNIVERSAL_NEWLINE_DECORATOR = 0x00000100, | |
RUBY_ECONV_CRLF_NEWLINE_DECORATOR = 0x00001000, | |
RUBY_ECONV_CR_NEWLINE_DECORATOR = 0x00002000, | |
RUBY_ECONV_XML_TEXT_DECORATOR = 0x00004000, | |
RUBY_ECONV_XML_ATTR_CONTENT_DECORATOR = 0x00008000, | |
RUBY_ECONV_STATEFUL_DECORATOR_MASK = 0x00f00000, | |
RUBY_ECONV_XML_ATTR_QUOTE_DECORATOR = 0x00100000, | |
RUBY_ECONV_DEFAULT_NEWLINE_DECORATOR = 0x00000000, | |
/* end of flags for rb_econv_open */ | |
/* flags for rb_econv_convert */ | |
RUBY_ECONV_PARTIAL_INPUT = 0x00010000, | |
RUBY_ECONV_AFTER_OUTPUT = 0x00020000, | |
/* end of flags for rb_econv_convert */ | |
}; | |
//#define ECONV_ERROR_HANDLER_MASK RUBY_ECONV_ERROR_HANDLER_MASK | |
#define ECONV_INVALID_MASK RUBY_ECONV_INVALID_MASK | |
#define ECONV_INVALID_REPLACE RUBY_ECONV_INVALID_REPLACE | |
#define ECONV_UNDEF_MASK RUBY_ECONV_UNDEF_MASK | |
#define ECONV_UNDEF_REPLACE RUBY_ECONV_UNDEF_REPLACE | |
#define ECONV_UNDEF_HEX_CHARREF RUBY_ECONV_UNDEF_HEX_CHARREF | |
//#define ECONV_DECORATOR_MASK RUBY_ECONV_DECORATOR_MASK | |
//#define ECONV_NEWLINE_DECORATOR_MASK RUBY_ECONV_NEWLINE_DECORATOR_MASK | |
//#define ECONV_NEWLINE_DECORATOR_READ_MASK RUBY_ECONV_NEWLINE_DECORATOR_READ_MASK | |
//#define ECONV_NEWLINE_DECORATOR_WRITE_MASK RUBY_ECONV_NEWLINE_DECORATOR_WRITE_MASK | |
#define ECONV_UNIVERSAL_NEWLINE_DECORATOR RUBY_ECONV_UNIVERSAL_NEWLINE_DECORATOR | |
#define ECONV_CRLF_NEWLINE_DECORATOR RUBY_ECONV_CRLF_NEWLINE_DECORATOR | |
#define ECONV_CR_NEWLINE_DECORATOR RUBY_ECONV_CR_NEWLINE_DECORATOR | |
#define ECONV_XML_TEXT_DECORATOR RUBY_ECONV_XML_TEXT_DECORATOR | |
#define ECONV_XML_ATTR_CONTENT_DECORATOR RUBY_ECONV_XML_ATTR_CONTENT_DECORATOR | |
//#define ECONV_STATEFUL_DECORATOR_MASK RUBY_ECONV_STATEFUL_DECORATOR_MASK | |
#define ECONV_XML_ATTR_QUOTE_DECORATOR RUBY_ECONV_XML_ATTR_QUOTE_DECORATOR | |
//#define ECONV_DEFAULT_NEWLINE_DECORATOR RUBY_ECONV_DEFAULT_NEWLINE_DECORATOR | |
/* end of flags for rb_econv_open */ | |
/* flags for rb_econv_convert */ | |
#define ECONV_PARTIAL_INPUT 0 | |
//#define ECONV_PARTIAL_INPUT RUBY_ECONV_PARTIAL_INPUT | |
#define ECONV_AFTER_OUTPUT RUBY_ECONV_AFTER_OUTPUT | |
/* end of flags for rb_econv_convert */ | |
EOF | |
PRI_VALUE = <<-EOF | |
#define PRI_VALUE_PREFIX "l" | |
#define PRI_LONG_PREFIX "l" | |
#define PRI_64_PREFIX PRI_LONG_PREFIX | |
#define RUBY_PRI_VALUE_MARK "\v" | |
#define PRIdVALUE PRI_VALUE_PREFIX"d" | |
#define PRIoVALUE PRI_VALUE_PREFIX"o" | |
#define PRIuVALUE PRI_VALUE_PREFIX"u" | |
#define PRIxVALUE PRI_VALUE_PREFIX"x" | |
#define PRIXVALUE PRI_VALUE_PREFIX"X" | |
#define PRIsVALUE PRI_VALUE_PREFIX"i" RUBY_PRI_VALUE_MARK | |
EOF | |
ECONV_STRUCT = <<-EOF | |
\\0 | |
struct rb_econv_t {}; | |
EOF | |
RESCUE_ENSURE = <<-EOF | |
VALUE rb_rescue(VALUE (*b_proc)(ANYARGS), VALUE data1, VALUE (*r_proc)(ANYARGS), VALUE data2); | |
VALUE rb_rescue2(VALUE (*b_proc)(ANYARGS), VALUE data1, VALUE (*r_proc)(ANYARGS), VALUE data2, ...); | |
VALUE rb_ensure(VALUE (*b_proc)(ANYARGS), VALUE data1, VALUE (*e_proc)(ANYARGS), VALUE data2); | |
VALUE rb_catch(const char *tag, VALUE (*func)(), VALUE data); | |
VALUE rb_catch_obj(VALUE t, VALUE (*func)(), VALUE data); | |
EOF | |
DEFINE_METHOD = <<-EOF | |
void rb_define_method(VALUE module, const char *name, VALUE (*function)(ANYARGS), int argc); | |
void rb_define_module_function(VALUE module, const char *name, VALUE (*function)(ANYARGS), int argc); | |
void rb_define_global_function(const char *name, VALUE (*function)(ANYARGS), int argc); | |
EOF | |
DEFINE_METHOD_INTERN = <<-EOF | |
void rb_define_protected_method(VALUE module, const char *name, VALUE (*function)(ANYARGS), int argc); | |
void rb_define_private_method(VALUE module, const char *name, VALUE (*function)(ANYARGS), int argc); | |
void rb_define_singleton_method(VALUE object, const char *name, VALUE (*function)(ANYARGS), int argc); | |
EOF | |
GET_OPEN_FILE = <<-EOF | |
#define GetOpenFile(file, pointer) ( \ | |
(pointer) = truffle_managed_malloc(sizeof(rb_io_t)), \ | |
(pointer)->mode = FIX2INT(rb_iv_get(file, "@mode")), \ | |
(pointer)->fd = FIX2INT(rb_iv_get(file, "@descriptor")), \ | |
rb_io_check_closed(pointer) \ | |
) | |
EOF | |
RBASIC = <<-EOF | |
struct RBasic { | |
// Empty | |
}; | |
EOF | |
RDATA_STRUCT = <<-EOF | |
typedef void (*RUBY_DATA_FUNC)(void*); | |
struct RData { | |
struct RBasic basic; | |
RUBY_DATA_FUNC dmark; | |
RUBY_DATA_FUNC dfree; | |
void *data; | |
}; | |
EOF | |
RB_DATA_TYPE_STRUCT = <<-EOF | |
struct rb_data_type_struct { | |
const char *wrap_struct_name; | |
struct { | |
RUBY_DATA_FUNC dmark; | |
RUBY_DATA_FUNC dfree; | |
size_t (*dsize)(const void *data); | |
void *reserved[2]; | |
} function; | |
const rb_data_type_t *parent; | |
void *data; | |
VALUE flags; | |
}; | |
EOF | |
RARRAY_LEN = <<-EOF | |
\\0 | |
long rb_array_len(VALUE a); | |
EOF | |
PATCH_SETS = [ | |
{:file => 'ruby/ruby.h', | |
:patches => [ | |
{:match => /static inline int\nrb_type\(VALUE obj\).*?^}/m, | |
:replacement => ''}, | |
{:match => /#define RB_TYPE_P\(obj, type\) \( \\.*?\)\)\)/m, | |
:replacement => RB_TYPE_P}, | |
{:match => /#include "ruby\/config.h"/, | |
:replacement => AFTER_CONFIG}, | |
# {:match => /^RUBY_SYMBOL_EXPORT_END/, | |
# :replacement => APPEND}, | |
{:match => /^RUBY_SYMBOL_EXPORT_END/, | |
:replacement => "\\0\n\n#include \"../truffle/ruby.h\""}, | |
{:match => /void \*rb_alloc_tmp_buffer\(volatile VALUE \*store, long len\)/, | |
:replacement => 'void *rb_alloc_tmp_buffer(VALUE *buffer_pointer, long length);'}, | |
{:match => /static inline int rb_type\(VALUE obj\);/, | |
:replacement => 'int rb_type(VALUE value);'}, | |
{:match => /void rb_free_tmp_buffer\(volatile VALUE \*store\)/, | |
:replacement => 'void rb_free_tmp_buffer(VALUE *store);'}, | |
{:match => /#define SYMBOL_P\(x\) RB_SYMBOL_P\(x\)/, | |
:replacement => 'bool SYMBOL_P(VALUE value);'}, | |
{:match => /#define CHR2FIX\(x\) RB_CHR2FIX\(x\)/, | |
:replacement => ''}, | |
{:match => /#define NUM2INT\(x\) RB_NUM2INT\(x\)/, | |
:replacement => 'int NUM2INT(VALUE value);'}, | |
{:match => /#define NUM2UINT\(x\) RB_NUM2UINT\(x\)/, | |
:replacement => 'unsigned int NUM2UINT(VALUE value);'}, | |
{:match => /#define NUM2LONG\(x\) RB_NUM2LONG\(x\)/, | |
:replacement => 'long NUM2LONG(VALUE value);'}, | |
{:match => /#define NUM2ULONG\(x\) RB_NUM2ULONG\(x\)/, | |
:replacement => 'unsigned long NUM2ULONG(VALUE value);'}, | |
{:match => /#define NUM2DBL\(x\) rb_num2dbl\(\(VALUE\)\(x\)\)/, | |
:replacement => 'double NUM2DBL(VALUE value);'}, | |
{:match => /#define FIX2INT\(x\) RB_FIX2INT\(x\)/, | |
:replacement => 'int FIX2INT(VALUE value);'}, | |
{:match => /#define FIX2UINT\(x\) RB_FIX2UINT\(x\)/, | |
:replacement => ''}, | |
{:match => /#define FIX2LONG\(x\) RB_FIX2LONG\(x\)/, | |
:replacement => 'long FIX2LONG(VALUE value);'}, | |
{:match => /#define FIX2ULONG\(x\) RB_FIX2ULONG\(x\)/, | |
:replacement => 'unsigned long FIX2ULONG(VALUE value);'}, | |
{:match => /#define INT2NUM\(x\) RB_INT2NUM\(x\)/, | |
:replacement => 'VALUE INT2NUM(long value);'}, | |
{:match => /#define INT2FIX\(i\) \(\(\(VALUE\)\(i\)\)<<1 \| RUBY_FIXNUM_FLAG\)/, | |
:replacement => 'VALUE INT2FIX(long value);'}, | |
{:match => /#define UINT2NUM\(x\) RB_UINT2NUM\(x\)/, | |
:replacement => 'VALUE UINT2NUM(unsigned int value);'}, | |
{:match => /#define LONG2NUM\(x\) RB_LONG2NUM\(x\)/, | |
:replacement => 'VALUE LONG2NUM(long value);'}, | |
{:match => /#define ULONG2NUM\(x\) RB_ULONG2NUM\(x\)/, | |
:replacement => 'VALUE ULONG2NUM(unsigned long value);'}, | |
{:match => /#define LONG2FIX\(i\) INT2FIX\(i\)/, | |
:replacement => 'VALUE LONG2FIX(long value);'}, | |
{:match => /#if SIZEOF_INT < SIZEOF_LONG\nstatic inline int\nrb_long2int_inline\(long n\).*?#endif/m, | |
:replacement => 'int rb_long2int(long value);'}, | |
{:match => /#define RB_NUM2CHR\(x\) rb_num2char_inline\(x\)/, | |
:replacement => 'char RB_NUM2CHR(VALUE x);'}, | |
{:match => /#define RB_FIXNUM_P\(f\) \(\(\(int\)\(SIGNED_VALUE\)\(f\)\)&RUBY_FIXNUM_FLAG\)/, | |
:replacement => 'int RB_FIXNUM_P(VALUE value);'}, | |
{:match => /#define RTEST\(v\) !\(\(\(VALUE\)\(v\) & ~Qnil\) == 0\)/, | |
:replacement => 'int RTEST(VALUE value);'}, | |
{:match => /#define RB_SPECIAL_CONST_P\(x\) \(RB_IMMEDIATE_P\(x\) \|\| !RTEST\(x\)\)/, | |
:replacement => SPECIAL_CONST_P}, | |
{:match => /#ifdef __GNUC__\n#define rb_special_const_p\(obj\).*?#endif/m, | |
:replacement => ''}, | |
{:match => /#define RSTRING_END\(str\).*?as.heap.len\)\)/m, | |
:replacement => 'char *RSTRING_END(VALUE string);'}, | |
{:match => /static inline VALUE\nrb_data_typed_object_make\(.*?}/m, | |
:replacement => 'VALUE rb_data_typed_object_make(VALUE ruby_class, const rb_data_type_t *type, void **data_pointer, size_t size);'}, | |
{:match => /#define rb_intern\(str\) \\.*?rb_intern\(str\)\)/m, | |
:replacement => ''}, | |
{:match => /#define RARRAY_LEN\(a\) rb_array_len\(a\)/, | |
:replacement => RARRAY_LEN}, | |
{:match => /#define RARRAY_LENINT\(ary\) rb_long2int\(RARRAY_LEN\(ary\)\)/, | |
:replacement => 'int RARRAY_LENINT(VALUE array);'}, | |
{:match => /#define RARRAY_AREF\(a, i\) \(RARRAY_CONST_PTR\(a\)\[i\]\)/, | |
:replacement => 'VALUE RARRAY_AREF(VALUE array, long index);'}, | |
{:match => /#define CLASS_OF\(v\) rb_class_of\(\(VALUE\)\(v\)\)/, | |
:replacement => 'VALUE CLASS_OF(VALUE object);'}, | |
{:match => /static inline VALUE\nrb_class_of\(VALUE obj\).*?^}/m, | |
:replacement => 'VALUE rb_class_of(VALUE object);'}, | |
{:match => /struct RData {.*?^};/m, | |
:replacement => RDATA}, | |
{:match => /#define RDATA\(obj\) \(R_CAST\(RData\)\(obj\)\)/, | |
:replacement => ''}, | |
{:match => /void rb_define_const\(VALUE,const char\*,VALUE\);/, | |
:replacement => 'VALUE rb_define_const(VALUE module, const char *name, VALUE value);'}, | |
{:match => /VALUE rb_gvar_var_getter\(ID id, void \*data, struct rb_global_variable \*gvar\);/, | |
:replacement => 'VALUE rb_gvar_var_getter(ID id, VALUE *var, void *gvar);'}, | |
{:match => /void rb_gvar_var_setter\(VALUE val, ID id, void \*data, struct rb_global_variable \*gvar\);/, | |
:replacement => 'void rb_gvar_var_setter(VALUE val, ID id, VALUE *var, void *g);'}, | |
{:match => /void rb_gvar_readonly_setter\(VALUE val, ID id, void \*data, struct rb_global_variable \*gvar\);/, | |
:replacement => 'void rb_gvar_readonly_setter(VALUE v, ID id, void *d, void *g);'}, | |
{:match => /RUBY_EXTERN VALUE rb_mKernel;.*?RUBY_EXTERN VALUE rb_stdin, rb_stdout, rb_stderr;/m, | |
:replacement => GENERATED_CONSTANTS}, | |
{:match => /VALUE rb_string_value\(volatile VALUE\*\);/, | |
:replacement => 'MUST_INLINE VALUE rb_string_value(VALUE *value_pointer);'}, | |
{:match => /char \*rb_string_value_ptr\(volatile VALUE\*\);/, | |
:replacement => 'MUST_INLINE char *rb_string_value_ptr(VALUE *value_pointer);'}, | |
{:match => /char \*rb_string_value_cstr\(volatile VALUE\*\);/, | |
:replacement => 'MUST_INLINE char *rb_string_value_cstr(VALUE *value_pointer);'}, | |
{:match => /#if defined HAVE_UINTPTR_T && 0.*?#endif/m, | |
:replacement => DEFINE_VALUE}, | |
{:match => /#define RSTRING_PTR\(str\).*?as.heap.ptr\)/m, | |
:replacement => RSTRING_PTR}, | |
{:match => /#define RSTRING_LEN\(str\).*?as.heap.len\)/m, | |
:replacement => RSTRING_LEN}, | |
{:match => /static inline void\nrb_obj_freeze_inline\(.*?^}/m, | |
:replacement => '#define rb_obj_freeze_inline(object) rb_obj_freeze(object)'}, | |
{:match => /static inline void\nrb_clone_setup\(.*?^}/m, | |
:replacement => ''}, | |
{:match => /static inline void\nrb_dup_setup\(.*?^}/m, | |
:replacement => ''}, | |
{:match => /static inline long\nrb_array_len\(.*?^}/m, | |
:replacement => ''}, | |
{:match => /static inline const VALUE \*\nrb_array_const_ptr\(.*?^}/m, | |
:replacement => ''}, | |
{:match => /static inline long\nrb_struct_len\(.*?^}/m, | |
:replacement => ''}, | |
{:match => /static inline const VALUE \*\nrb_struct_const_ptr\(.*?^}/m, | |
:replacement => ''}, | |
{:match => /#define RSTRING_GETMEM\(.*?->as.heap.len\)\)/m, | |
:replacement => '#define RSTRING_GETMEM(string, data_pointer, length_pointer) ((data_pointer) = RSTRING_PTR(string), (length_pointer) = rb_str_len(string))'}, | |
{:match => /#define RB_OBJ_FROZEN\(x\) \(!RB_FL_ABLE\(x\) \|\| RB_OBJ_FROZEN_RAW\(x\)\)/, | |
:replacement => '#define RB_OBJ_FROZEN(x) rb_obj_frozen_p(x)'}, | |
{:match => /#define RB_OBJ_INFECT\(.*?void\)0\)/m, | |
:replacement => '#define RB_OBJ_INFECT(a, b) rb_tr_obj_infect(a, b)'}, | |
{:match => /#define SafeStringValue\(.*?while \(0\)/m, | |
:replacement => '#define SafeStringValue StringValue'}, | |
{:match => /#define RB_ALLOC_N\(.*?#endif/m, | |
:replacement => ALLOC}, | |
{:match => /#define RB_NUM2SHORT.*?#define NUM2USHORT\(x\) RB_NUM2USHORT\(x\)/m, | |
:replacement => NUM2SHORT}, | |
{:match => /#define RB_FIX2SHORT.*?RB_FIX2SHORT\(x\)/m, | |
:replacement => '#define FIX2SHORT(x) (rb_fix2short((VALUE)(x)))'}, | |
{:match => /# define NUM2LL\(x\) RB_NUM2LL\(x\)/, | |
:replacement => '#define NUM2LL(x) rb_num2ll(x)'}, | |
{:match => /#define NIL_P\(v\) !\(\(VALUE\)\(v\) != Qnil\)/, | |
:replacement => '#define NIL_P RB_NIL_P'}, | |
{:match => /#define RB_BUILTIN_TYPE\(x\) \(int\)\(\(\(struct RBasic\*\)\(x\)\)->flags & RUBY_T_MASK\)/, | |
:replacement => '#define RB_BUILTIN_TYPE(OBJECT) rb_type(OBJECT)'}, | |
{:match => /#ifdef __GNUC__\n#define rb_type_p\(.*?#endif/m, | |
:replacement => '#define rb_type_p(object, type) (rb_type(object) == (type))'}, | |
{:match => /#define RB_OBJ_TAINTABLE\(.*?rb_obj_freeze_inline\(\(VALUE\)x\)/m, | |
:replacement => TAINT_FREEZE}, | |
{:match => /#if defined PRIdPTR && !defined PRI_VALUE_PREFIX.*?^#endif.*?#endif/m, | |
:replacement => PRI_VALUE}, | |
{:match => /#define RSTRING_LENINT\(str\) rb_long2int\(RSTRING_LEN\(str\)\)/, | |
:replacement => '#define RSTRING_LENINT(str) rb_str_len(str)'}, | |
{:match => /#ifdef __GNUC__\n\/\* __builtin_constant_p and.*?#endif/m, | |
:replacement => '#define rb_intern_const(str) rb_intern2((str), strlen(str))'}, | |
{:match => /#define RARRAY_PTR\(a\) \(\(VALUE \*\)RARRAY_CONST_PTR\(RB_OBJ_WB_UNPROTECT_FOR\(ARRAY, a\)\)\)/, | |
:replacement => '#define RARRAY_PTR(array) ((VALUE *)array)'}, | |
{:match => /VALUE rb_iterate\(VALUE\(\*\)\(VALUE\),VALUE,VALUE\(\*\)\(ANYARGS\),VALUE\);/, | |
:replacement => 'VALUE rb_iterate(VALUE (*function)(), VALUE arg1, VALUE (*block)(), VALUE arg2);'}, | |
{:match => /#define RB_BLOCK_CALL_FUNC_ARGLIST\(.*?VALUE blockarg/m, | |
:replacement => '#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg) VALUE yielded_arg, VALUE callback_arg, int __args_count, const VALUE *__args, VALUE __block_arg'}, | |
{:match => /#if defined RB_BLOCK_CALL_FUNC_STRICT && RB_BLOCK_CALL_FUNC_STRICT.*?#endif/m, | |
:replacement => 'typedef rb_block_call_func *rb_block_call_func_t;'}, | |
{:match => /void rb_define_hooked_variable\(const char\*,VALUE\*,VALUE\(\*\)\(ANYARGS\),void\(\*\)\(ANYARGS\)\);/, | |
:replacement => 'void rb_define_hooked_variable(const char *name, VALUE *var, VALUE (*getter)(ANYARGS), void (*setter)(ANYARGS));'}, | |
{:match => /VALUE rb_rescue\(.*?\.\.\.\);.*?VALUE rb_catch_obj\(VALUE,VALUE\(\*\)\(ANYARGS\),VALUE\);/m, | |
:replacement => RESCUE_ENSURE}, | |
{:match => /void rb_define_method\(.*?void rb_define_global_function\(.*?int\);/m, | |
:replacement => DEFINE_METHOD}, | |
{:match => /#define RB_GC_GUARD\(v\) \(\*rb_gc_guarded_ptr_val\(&\(v\),\(v\)\)\)/, | |
:replacement => '#define RB_GC_GUARD(v) (v)'}, | |
{:match => /#define RB_GC_GUARD\(v\) \(\*RB_GC_GUARD_PTR\(&\(v\)\)\)/, | |
:replacement => '#define RB_GC_GUARD(v) (v)'}, | |
{:match => /#define FilePathValue\(v\) \(RB_GC_GUARD\(v\) = rb_get_path\(v\)\)/, | |
:replacement => '#define FilePathValue(v) (v = rb_get_path(v))'}, | |
{:match => /struct RBasic {.*?^}/m, | |
:replacement => RBASIC}, | |
{:match => /typedef void \(\*RUBY_DATA_FUNC\)\(void\*\);/, | |
:replacement => ''}, | |
{:match => /struct RData {.*?^}/m, | |
:replacement => RDATA_STRUCT}, | |
{:match => /#define rb_data_object_get RUBY_MACRO_SELECT\(rb_data_object_get_, RUBY_UNTYPED_DATA_WARNING\)/, | |
:replacement => '#define rb_data_object_get DATA_PTR'}, | |
{:match => /#ifndef rb_data_object_alloc.*?#endif/m, | |
:replacement => '#define rb_data_object_alloc(klass, data, dmark, dfree) rb_data_object_wrap(klass, data, dmark, dfree)'}, | |
{:match => /struct rb_data_type_struct {.*?^}/m, | |
:replacement => RB_DATA_TYPE_STRUCT}, | |
{:match => /#define RTYPEDDATA\(obj\) \(R_CAST\(RTypedData\)\(obj\)\)/, | |
:replacement => '#define RTYPEDDATA(value) ((struct RTypedData *)RDATA(value))'}, | |
{:match => /#define SYM2ID\(x\) RB_SYM2ID\(x\)/, | |
:replacement => 'ID SYM2ID(VALUE value);'}, | |
{:match => /#define ID2SYM\(x\) RB_ID2SYM\(x\)/, | |
:replacement => 'VALUE ID2SYM(ID value);'}, | |
{:match => /void rb_global_variable\(VALUE\*\);/, | |
:replacement => '#define rb_global_variable(address) ;' }, | |
{:match => /static inline void \*\nrb_data_object_get\(.*?^}/m, | |
:replacement => '#define rb_data_object_get DATA_PTR'} | |
] | |
}, # end ruby.h | |
{:file => 'ruby/intern.h', | |
:patches => [ | |
{:match => /#ifdef __GNUC__\n#define rb_check_frozen\(obj\).*?#endif/m, | |
:replacement => ''}, | |
{:match => /#define rb_str_new\(.*?}\)/m, | |
:replacement => ''}, | |
{:match => /#define rb_str_new_cstr\(.*?}\)/m, | |
:replacement => 'VALUE rb_str_new_cstr(const char *string);'}, | |
{:match => /#define rb_tainted_str_new_cstr\(.*?}\)/m, | |
:replacement => ''}, | |
{:match => /#define rb_str_cat2 rb_str_cat_cstr/, | |
:replacement => ''}, | |
{:match => /#define rb_str_buf_new_cstr\(.*?}\)/m, | |
:replacement => ''}, | |
{:match => /#define rb_str_buf_cat rb_str_cat/, | |
:replacement => ''}, | |
{:match => /#define rb_external_str_new_cstr\(.*?}\)/m, | |
:replacement => ''}, | |
{:match => /#define rb_locale_str_new_cstr\(str\).*?}\)/m, | |
:replacement => ''}, | |
{:match => /#define rb_usascii_str_new\(.*?}\)/m, | |
:replacement => ''}, | |
{:match => /#define rb_usascii_str_new_cstr\(.*?}\)/m, | |
:replacement => ''}, | |
{:match => /static inline void\nrb_check_arity\(.*?^}/m, | |
:replacement => 'void rb_check_arity(int argc, int min, int max);'}, | |
{:match => /#define rb_exc_new_cstr\(.*?^}\)/m, | |
:replacement => ''}, | |
{:match => /VALUE rb_attr_get\(VALUE, ID\);/, | |
:replacement => 'VALUE rb_attr_get(VALUE object, const char *name);'}, | |
{:match => /void rb_const_set\(VALUE, ID, VALUE\);/, | |
:replacement => 'VALUE rb_const_set(VALUE module, ID name, VALUE value);'}, | |
{:match => /int rb_reg_options\(VALUE\);/, | |
:replacement => 'VALUE rb_reg_options(VALUE re);'}, | |
{:match => /int rb_range_values\(VALUE range, VALUE \*begp, VALUE \*endp, int \*exclp\);/, | |
:replacement => 'MUST_INLINE int rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp);'}, | |
{:match => /void rb_set_end_proc\(void \(\*\)\(VALUE\), VALUE\);/, | |
:replacement => 'void rb_set_end_proc(void (*func)(VALUE), VALUE data);'}, | |
{:match => /VALUE rb_obj_as_string\(VALUE\);/, | |
:replacement => '#define rb_obj_as_string(object) rb_any_to_s(object)'}, | |
{:match => /VALUE rb_str_dup\(VALUE\);/, | |
:replacement => '#define rb_str_dup(string) rb_obj_dup(string)'}, | |
{:match => /VALUE rb_str_resurrect\(VALUE str\);/, | |
:replacement => '#define rb_str_resurrect(string) rb_obj_dup(string)'}, | |
{:match => /VALUE rb_str_freeze\(VALUE\);/, | |
:replacement => '#define rb_str_freeze(string) rb_obj_freeze(string)'}, | |
{:match => /VALUE rb_str_inspect\(VALUE\);/, | |
:replacement => '#define rb_str_inspect(string) rb_inspect(string)'}, | |
{:match => /VALUE rb_ary_dup\(VALUE\);/, | |
:replacement => '#define rb_ary_dup(array) rb_obj_dup(array)'}, | |
{:match => /VALUE rb_ary_freeze\(VALUE\);/, | |
:replacement => '#define rb_ary_freeze(array) rb_obj_freeze(array)'}, | |
{:match => /VALUE rb_assoc_new\(VALUE, VALUE\);/, | |
:replacement => '#define rb_assoc_new(a, b) rb_ary_new3(2, a, b)'}, | |
{:match => /VALUE rb_hash_freeze\(VALUE\);/, | |
:replacement => '#define rb_hash_freeze(array) rb_obj_freeze(array)'}, | |
{:match => /VALUE rb_proc_new\(VALUE \(\*\)\(ANYARGS\/\* VALUE yieldarg\[, VALUE procarg\] \*\/\), VALUE\);/, | |
:replacement => 'VALUE rb_proc_new(VALUE (*function)(ANYARGS), VALUE value);'}, | |
{:match => /VALUE rb_protect\(VALUE \(\*\)\(VALUE\), VALUE, int\*\);/, | |
:replacement => 'VALUE rb_protect(VALUE (*function)(VALUE), VALUE data, int *status);'}, | |
{:match => /void rb_define_protected_method\(.*?rb_define_singleton_method\(.*?int\);/m, | |
:replacement => DEFINE_METHOD_INTERN}, | |
{:match => /void rb_update_max_fd\(int fd\);/, | |
:replacement => '#define rb_update_max_fd(fd) {}'} | |
] | |
}, # end intern.h | |
{:file => 'ruby/encoding.h', | |
:patches => [ | |
{:match => /typedef const OnigEncodingType rb_encoding;/, | |
:replacement => RB_ENCODING}, | |
{:match => /#define MBCLEN_NEEDMORE_P\(ret\) ONIGENC_MBCLEN_NEEDMORE_P\(ret\)/, | |
:replacement => 'int MBCLEN_NEEDMORE_P(int r);'}, | |
{:match => /#define MBCLEN_NEEDMORE_LEN\(ret\) ONIGENC_MBCLEN_NEEDMORE_LEN\(ret\)/, | |
:replacement => 'int MBCLEN_NEEDMORE_LEN(int r);'}, | |
{:match => /#define MBCLEN_CHARFOUND_P\(ret\) ONIGENC_MBCLEN_CHARFOUND_P\(ret\)/, | |
:replacement => 'int MBCLEN_CHARFOUND_P(int r);'}, | |
{:match => /#define MBCLEN_CHARFOUND_LEN\(ret\) ONIGENC_MBCLEN_CHARFOUND_LEN\(ret\)/, | |
:replacement => 'int MBCLEN_CHARFOUND_LEN(int r);'}, | |
{:match => /VALUE rb_external_str_new_with_enc\(const char \*ptr, long len, rb_encoding \*\);/, | |
:replacement => STR_WITH_ENC}, | |
{:match => /#define rb_enc_asciicompat\(enc\) \(rb_enc_mbminlen\(enc\)==1 && !rb_enc_dummy_p\(enc\)\)/, | |
:replacement => ''}, | |
{:match => /#define RB_ENC_CODERANGE\(obj\) \(\(int\)RBASIC\(obj\)->flags & RUBY_ENC_CODERANGE_MASK\)/, | |
:replacement => 'enum ruby_coderange_type RB_ENC_CODERANGE(VALUE obj);'}, | |
{:match => /#define rb_enc_str_new\(str.*?}\)/m, | |
:replacement => ''}, | |
{:match => /#define rb_enc_left_char_head\(s,p,e,enc\) \(\(char \*\)onigenc_get_left_adjust_char_head\(\(enc\),\(UChar\*\)\(s\),\(UChar\*\)\(p\),\(UChar\*\)\(e\)\)\)/, | |
:replacement => 'char* rb_enc_left_char_head(char *start, char *p, char *end, rb_encoding *enc);'}, | |
{:match => /#define rb_enc_mbmaxlen\(enc\) \(enc\)->max_enc_len/, | |
:replacement => 'int rb_enc_mbmaxlen(rb_encoding *enc);'}, | |
{:match => /#define rb_enc_mbminlen\(enc\) \(enc\)->min_enc_len/, | |
:replacement => 'int rb_enc_mbminlen(rb_encoding *enc);'}, | |
{:match => /enum ruby_coderange_type {.*?^};/m, | |
:replacement => RUBY_CODERANGE_TYPE }, | |
{:match => /enum ruby_econv_flag_type {.*?RUBY_ECONV_FLAGS_PLACEHOLDER};/m, | |
:replacement => ECONV}, | |
# {:match => /#define RB_ENCODING_GET\(.*?rb_enc_get_index\(obj\)\)/m, | |
# :replacement => '#define RB_ENCODING_GET(obj) rb_enc_get(obj)'}, | |
{:match => /\/\* econv stuff \*\//, | |
:replacement => ECONV_STRUCT} | |
] | |
}, # end encoding.h | |
{:file => 'ruby/io.h', | |
:patches => [{:match => /typedef struct rb_io_t {.*?^} rb_io_t;/m, | |
:replacement => RB_IO}, | |
{:match => /#define GetOpenFile\(obj,fp\) rb_io_check_closed\(\(fp\) = RFILE\(rb_io_taint_check\(obj\)\)->fptr\)/, | |
:replacement => GET_OPEN_FILE} | |
]}, | |
{:file => 'ruby/thread_native.h', | |
:patches => [{ | |
:match => /typedef pthread_t rb_nativethread_id_t;.*?typedef pthread_mutex_t rb_nativethread_lock_t;/m, | |
:replacement => RB_NATIVE_THREAD | |
}, | |
{:match => /void rb_nativethread_lock_initialize\(rb_nativethread_lock_t \*lock\);/, | |
:replacement => 'MUST_INLINE int rb_nativethread_lock_initialize(rb_nativethread_lock_t *lock);'}, | |
{:match => /void rb_nativethread_lock_destroy\(rb_nativethread_lock_t \*lock\);/, | |
:replacement => 'MUST_INLINE int rb_nativethread_lock_destroy(rb_nativethread_lock_t *lock);'}, | |
{:match => /void rb_nativethread_lock_lock\(rb_nativethread_lock_t \*lock\);/, | |
:replacement => 'MUST_INLINE int rb_nativethread_lock_lock(rb_nativethread_lock_t *lock);'}, | |
{:match => /void rb_nativethread_lock_unlock\(rb_nativethread_lock_t \*lock\);/, | |
:replacement => 'MUST_INLINE int rb_nativethread_lock_unlock(rb_nativethread_lock_t *lock);'}, | |
]}, | |
{:file => 'ruby/thread.h', | |
:patches => [{:match => /void \*rb_thread_call_with_gvl\(void \*\(\*func\)\(void \*\), void \*data1\);/, | |
:replacement => 'void *rb_thread_call_with_gvl(gvl_call function, void *data1);'}, | |
{:match => /void \*rb_thread_call_without_gvl\(void \*\(\*func\)\(void \*\), void \*data1,.*?rb_unblock_function_t \*ubf, void \*data2\);/m, | |
:replacement => 'void *rb_thread_call_without_gvl(gvl_call function, void *data1, rb_unblock_function_t *unblock_function, void *data2);'}, | |
{:match => /void \*rb_thread_call_without_gvl2\(void \*\(\*func\)\(void \*\), void \*data1,.*?rb_unblock_function_t \*ubf, void \*data2\);/m, | |
:replacement => '#define rb_thread_call_without_gvl2 rb_thread_call_without_gvl'} | |
]}, | |
{:file => 'ruby/subst.h', | |
:patches => [ | |
{:match => /#define snprintf ruby_snprintf/, | |
:replacement => ''} | |
]} | |
] | |
patching = true # switch to enable patching | |
PATCH_SETS.each do |patch_set| | |
file = patch_set[:file] | |
destfile = File.join(TRUFFLERUBY_CEXT_LIB_DIR, file) | |
sourcefile = File.join(RUBY_INCLUDE_DIR, file) | |
tempfile = File.open(destfile, 'w') | |
f = File.new(sourcefile) | |
contents = f.read | |
patches = patch_set[:patches] | |
patches.each do |patch| | |
if patching | |
match = contents.match(patch[:match]) | |
puts "MATCH: #{match[0]} for patch:#{patch[:match]}" | |
after = contents.gsub(patch[:match], patch[:replacement]) | |
raise "no change" if after == contents | |
contents = after | |
end | |
end | |
tempfile.write contents | |
f.close | |
tempfile.close | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment