Gestionnaire de fichiers - Editer - /opt/cpanel/ea-ruby24/root/usr/share/ri/system/page-extension_rdoc.ri
Arrière
U:RDoc::TopLevel[ i I"extension.rdoc:EFcRDoc::Parser::Simpleo:RDoc::Markup::Document:@parts[=S:RDoc::Markup::Heading: leveli: textI"*Creating Extension Libraries for Ruby;To:RDoc::Markup::BlankLine o:RDoc::Markup::Paragraph;[I"EThis document explains how to make extension libraries for Ruby.;T@ S; ; i;I"Basic Knowledge;T@ o; ;[I"JIn C, variables have types and data do not have types. In contrast, ;TI"HRuby variables do not have a static type, and data themselves have ;TI"Dtypes, so data will need to be converted between the languages.;T@ o; ;[I"JData in Ruby are represented by the C type `VALUE'. Each VALUE data ;TI"has its data type.;T@ o; ;[I"2To retrieve C data from a VALUE, you need to:;T@ o:RDoc::Markup::List: @type:NUMBER:@items[o:RDoc::Markup::ListItem:@label0;[o; ;[I"#Identify the VALUE's data type;To;;0;[o; ;[I""Convert the VALUE into C data;T@ o; ;[I"BConverting to the wrong data type may cause serious problems.;T@ S; ; i;I"Data Types;T@ o; ;[I"7The Ruby interpreter has the following data types:;T@ o;;: NOTE;[o;;[I"T_NIL ;T;[o; ;[I"nil;To;;[I"T_OBJECT ;T;[o; ;[I"ordinary object;To;;[I"T_CLASS ;T;[o; ;[I" class;To;;[I"T_MODULE ;T;[o; ;[I"module;To;;[I"T_FLOAT ;T;[o; ;[I"floating point number;To;;[I"T_STRING ;T;[o; ;[I"string;To;;[I"T_REGEXP ;T;[o; ;[I"regular expression;To;;[I"T_ARRAY ;T;[o; ;[I" array;To;;[I"T_HASH ;T;[o; ;[I"associative array;To;;[I"T_STRUCT ;T;[o; ;[I"(Ruby) structure;To;;[I"T_BIGNUM ;T;[o; ;[I"multi precision integer;To;;[I"T_FIXNUM ;T;[o; ;[I"#Fixnum(31bit or 63bit integer);To;;[I"T_COMPLEX ;T;[o; ;[I"complex number;To;;[I"T_RATIONAL ;T;[o; ;[I"rational number;To;;[I"T_FILE ;T;[o; ;[I"IO;To;;[I"T_TRUE ;T;[o; ;[I" true;To;;[I"T_FALSE ;T;[o; ;[I" false;To;;[I"T_DATA ;T;[o; ;[I" data;To;;[I"T_SYMBOL ;T;[o; ;[I"symbol;T@ o; ;[I"@In addition, there are several other types used internally:;T@ o;;;;[ o;;[I"T_ICLASS ;T;[o; ;[I"included module;To;;[I"T_MATCH ;T;[o; ;[I"MatchData object;To;;[I"T_UNDEF ;T;[o; ;[I"undefined;To;;[I"T_NODE ;T;[o; ;[I"syntax tree node;To;;[I"T_ZOMBIE ;T;[o; ;[I"!object awaiting finalization;T@ o; ;[I"7Most of the types are represented by C structures.;T@ S; ; i;I"!Check Data Type of the VALUE;T@ o; ;[I"JThe macro TYPE() defined in ruby.h shows the data type of the VALUE. ;TI"KTYPE() returns the constant number T_XXXX described above. To handle ;TI"9data types, your code will look something like this:;T@ o:RDoc::Markup::Verbatim;[I"switch (TYPE(obj)) { ;TI" case T_FIXNUM: ;TI" process Fixnum ;TI" break; ;TI" case T_STRING: ;TI" process String ;TI" break; ;TI" case T_ARRAY: ;TI" /* process Array */ ;TI" break; ;TI" default: ;TI" /* raise exception */ ;TI"5 rb_raise(rb_eTypeError, "not valid value"); ;TI" break; ;TI"} ;T:@format0o; ;[I"*There is the data type check function;T@ o;;[I",void Check_Type(VALUE value, int type) ;T;0o; ;[I"Cwhich raises an exception if the VALUE does not have the type ;TI"specified.;T@ o; ;[I"<There are also faster check macros for fixnums and nil.;T@ o;;[I"FIXNUM_P(obj) ;TI"NIL_P(obj) ;T;0S; ; i;I"Convert VALUE into C Data;T@ o; ;[ I"CThe data for type T_NIL, T_FALSE, T_TRUE are nil, false, true ;TI";respectively. They are singletons for the data type. ;TI":The equivalent C constants are: Qnil, Qfalse, Qtrue. ;TI"@Note that Qfalse is false in C also (i.e. 0), but not Qnil.;T@ o; ;[I"AThe T_FIXNUM data is a 31bit or 63bit length fixed integer. ;TI"BThis size depends on the size of long: if long is 32bit then ;TI"AT_FIXNUM is 31bit, if long is 64bit then T_FIXNUM is 63bit. ;TI";T_FIXNUM can be converted to a C integer by using the ;TI"GFIX2INT() macro or FIX2LONG(). Though you have to check that the ;TI"Kdata is really FIXNUM before using them, they are faster. FIX2LONG() ;TI"Enever raises exceptions, but FIX2INT() raises RangeError if the ;TI"7result is bigger or smaller than the size of int. ;TI"EThere are also NUM2INT() and NUM2LONG() which converts any Ruby ;TI"Bnumbers into C integers. These macros include a type check, ;TI"Iso an exception will be raised if the conversion failed. NUM2DBL() ;TI"Dcan be used to retrieve the double float value in the same way.;T@ o; ;[I"You can use the macros ;TI"EStringValue() and StringValuePtr() to get a char* from a VALUE. ;TI"NStringValue(var) replaces var's value with the result of "var.to_str()". ;TI"IStringValuePtr(var) does the same replacement and returns the char* ;TI"Krepresentation of var. These macros will skip the replacement if var ;TI"His a String. Notice that the macros take only the lvalue as their ;TI"3argument, to change the value of var in place.;T@ o; ;[I"FYou can also use the macro named StringValueCStr(). This is just ;TI"Jlike StringValuePtr(), but always adds a NUL character at the end of ;TI"Kthe result. If the result contains a NUL character, this macro causes ;TI""the ArgumentError exception. ;TI"JStringValuePtr() doesn't guarantee the existence of a NUL at the end ;TI"3of the result, and the result may contain NUL.;T@ o; ;[I"JOther data types have corresponding C structures, e.g. struct RArray ;TI"Hfor T_ARRAY etc. The VALUE of the type which has the corresponding ;TI"Gstructure can be cast to retrieve the pointer to the struct. The ;TI"Ecasting macro will be of the form RXXXX for each data type; for ;TI"Iinstance, RARRAY(obj). See "ruby.h". However, we do not recommend ;TI"Nto access RXXXX data directly because these data structures are complex. ;TI"IUse corresponding rb_xxx() functions to access the internal struct. ;TI"MFor example, to access an entry of array, use rb_ary_entry(ary, offset) ;TI"(and rb_ary_store(ary, offset, obj).;T@ o; ;[I"HThere are some accessing macros for structure members, for example ;TI"H`RSTRING_LEN(str)' to get the size of the Ruby String object. The ;TI"<allocated region can be accessed by `RSTRING_PTR(str)'.;T@ o; ;[I"KNotice: Do not change the value of the structure directly, unless you ;TI"Fare responsible for the result. This ends up being the cause of ;TI"interesting bugs.;T@ S; ; i;I"Convert C Data into VALUE;T@ o; ;[I"&To convert C data to Ruby values:;T@ o;;;;[o;;[I"FIXNUM ;T;[o; ;[I"Cleft shift 1 bit, and turn on its least significant bit (LSB).;T@ o;;[I"Other pointer values ;T;[o; ;[I"cast to VALUE.;T@ o; ;[I"OYou can determine whether a VALUE is a pointer or not by checking its LSB.;T@ o; ;[I"ONotice: Ruby does not allow arbitrary pointer values to be a VALUE. They ;TI"Mshould be pointers to the structures which Ruby knows about. The known ;TI"(structures are defined in <ruby.h>.;T@ o; ;[I";To convert C numbers to Ruby values, use these macros:;T@ o;;;;[o;;[I"INT2FIX() ;T;[o; ;[I" for integers within 31bits.;To;;[I"INT2NUM() ;T;[o; ;[I""for arbitrary sized integers.;T@ o; ;[I"LINT2NUM() converts an integer into a Bignum if it is out of the FIXNUM ;TI" range, but is a bit slower.;T@ S; ; i;I"Manipulating Ruby Data;T@ o; ;[ I"IAs I already mentioned, it is not recommended to modify an object's ;TI"Linternal structure. To manipulate objects, use the functions supplied ;TI"Iby the Ruby interpreter. Some (not all) of the useful functions are ;TI"listed below:;T@ S; ; i ;I"String Functions;T@ o;;;;[o;;[I"+rb_str_new(const char *ptr, long len) ;T;[o; ;[I"Creates a new Ruby string.;T@ o;;[I""rb_str_new2(const char *ptr) ;TI"&rb_str_new_cstr(const char *ptr) ;T;[o; ;[I"GCreates a new Ruby string from a C string. This is equivalent to ;TI""rb_str_new(ptr, strlen(ptr)).;T@ o;;[I")rb_str_new_literal(const char *ptr) ;T;[o; ;[I"7Creates a new Ruby string from a C string literal.;T@ o;;[I"3rb_tainted_str_new(const char *ptr, long len) ;T;[o; ;[I"DCreates a new tainted Ruby string. Strings from external data ;TI"sources should be tainted.;T@ o;;[I"*rb_tainted_str_new2(const char *ptr) ;TI".rb_tainted_str_new_cstr(const char *ptr) ;T;[o; ;[I"7Creates a new tainted Ruby string from a C string.;T@ o;;[I")rb_sprintf(const char *format, ...) ;TI"1rb_vsprintf(const char *format, va_list ap) ;T;[ o; ;[I"5Creates a new Ruby string with printf(3) format.;T@ o; ;[ I"JNote: In the format string, "%"PRIsVALUE can be used for Object#to_s ;TI"I(or Object#inspect if '+' flag is set) output (and related argument ;TI"Fmust be a VALUE). Since it conflicts with "%i", for integers in ;TI"format strings, use "%d".;T@ o;;[I"6rb_str_cat(VALUE str, const char *ptr, long len) ;T;[o; ;[I";Appends len bytes of data from ptr to the Ruby string.;T@ o;;[I"-rb_str_cat2(VALUE str, const char* ptr) ;TI"1rb_str_cat_cstr(VALUE str, const char* ptr) ;T;[o; ;[I"@Appends C string ptr to Ruby string str. This function is ;TI"5equivalent to rb_str_cat(str, ptr, strlen(ptr)).;T@ o;;[I"5rb_str_catf(VALUE str, const char* format, ...) ;TI"=rb_str_vcatf(VALUE str, const char* format, va_list ap) ;T;[o; ;[ I"EAppends C string format and successive arguments to Ruby string ;TI"Astr according to a printf-like format. These functions are ;TI"Aequivalent to rb_str_cat2(str, rb_sprintf(format, ...)) and ;TI"=rb_str_cat2(str, rb_vsprintf(format, ap)), respectively.;T@ o;;[I"Arb_enc_str_new(const char *ptr, long len, rb_encoding *enc) ;TI"<rb_enc_str_new_cstr(const char *ptr, rb_encoding *enc) ;T;[o; ;[I";Creates a new Ruby string with the specified encoding.;T@ o;;[I"-rb_enc_str_new_literal(const char *ptr) ;T;[o; ;[I"JCreates a new Ruby string from a C string literal with the specified ;TI"encoding.;T@ o;;[I"3rb_usascii_str_new(const char *ptr, long len) ;TI".rb_usascii_str_new_cstr(const char *ptr) ;T;[o; ;[I"6Creates a new Ruby string with encoding US-ASCII.;T@ o;;[I"1rb_usascii_str_new_literal(const char *ptr) ;T;[o; ;[I"ECreates a new Ruby string from a C string literal with encoding ;TI"US-ASCII.;T@ o;;[I"0rb_utf8_str_new(const char *ptr, long len) ;TI"+rb_utf8_str_new_cstr(const char *ptr) ;T;[o; ;[I"3Creates a new Ruby string with encoding UTF-8.;T@ o;;[I".rb_utf8_str_new_literal(const char *ptr) ;T;[o; ;[I"ECreates a new Ruby string from a C string literal with encoding ;TI"UTF-8.;T@ o;;[I"(rb_str_resize(VALUE str, long len) ;T;[o; ;[I"IResizes a Ruby string to len bytes. If str is not modifiable, this ;TI"Efunction raises an exception. The length of str must be set in ;TI"Eadvance. If len is less than the old length the content beyond ;TI"Hlen bytes is discarded, else if len is greater than the old length ;TI"Gthe content beyond the old length bytes will not be preserved but ;TI"Hwill be garbage. Note that RSTRING_PTR(str) may change by calling ;TI"this function.;T@ o;;[I")rb_str_set_len(VALUE str, long len) ;T;[o; ;[ I"GSets the length of a Ruby string. If str is not modifiable, this ;TI"Hfunction raises an exception. This function preserves the content ;TI"Hup to len bytes, regardless RSTRING_LEN(str). len must not exceed ;TI"the capacity of str.;T@ S; ; i ;I"Array Functions;T@ o;;;;[ o;;[I"rb_ary_new() ;T;[o; ;[I"'Creates an array with no elements.;T@ o;;[I"rb_ary_new2(long len) ;TI"rb_ary_new_capa(long len) ;T;[o; ;[I"CCreates an array with no elements, allocating internal buffer ;TI"for len elements.;T@ o;;[I"rb_ary_new3(long n, ...) ;TI"'rb_ary_new_from_args(long n, ...) ;T;[o; ;[I"3Creates an n-element array from the arguments.;T@ o;;[I"&rb_ary_new4(long n, VALUE *elts) ;TI"1rb_ary_new_from_values(long n, VALUE *elts) ;T;[o; ;[I"/Creates an n-element array from a C array.;T@ o;;[I"rb_ary_to_ary(VALUE obj) ;T;[o; ;[I"(Converts the object into an array. ;TI"!Equivalent to Object#to_ary.;T@ o; ;[I"PThere are many functions to operate an array. They may dump core if other ;TI"types are given.;T@ o;;;;[o;;[I"/rb_ary_aref(argc, VALUE *argv, VALUE ary) ;T;[o; ;[I"Equivalent to Array#[].;T@ o;;[I"*rb_ary_entry(VALUE ary, long offset) ;T;[o; ;[I"\ary[offset];T@ o;;[I"5rb_ary_store(VALUE ary, long offset, VALUE obj) ;T;[o; ;[I"\ary[offset] = obj;T@ o;;[I"2rb_ary_subseq(VALUE ary, long beg, long len) ;T;[o; ;[I"ary[beg, len];T@ o;;[ I"'rb_ary_push(VALUE ary, VALUE val) ;TI"rb_ary_pop(VALUE ary) ;TI"rb_ary_shift(VALUE ary) ;TI"*rb_ary_unshift(VALUE ary, VALUE val) ;T;[o; ;[I".ary.push, ary.pop, ary.shift, ary.unshift;T@ o;;[I"7rb_ary_cat(VALUE ary, const VALUE *ptr, long len) ;T;[o; ;[I";Appends len elements of objects from ptr to the array.;T@ S; ; i;I"Extending Ruby with C;T@ S; ; i;I" Adding New Features to Ruby;T@ o; ;[I"CYou can add new features (classes, methods, etc.) to the Ruby ;TI"Hinterpreter. Ruby provides APIs for defining the following things:;T@ o;;:BULLET;[o;;0;[o; ;[I"Classes, Modules;To;;0;[o; ;[I"Methods, Singleton Methods;To;;0;[o; ;[I"Constants;T@ S; ; i ;I" Class and Module Definition;T@ o; ;[I":To define a class or module, use the functions below:;T@ o;;[I":VALUE rb_define_class(const char *name, VALUE super) ;TI".VALUE rb_define_module(const char *name) ;T;0o; ;[I"HThese functions return the newly created class or module. You may ;TI">want to save this reference into a variable to use later.;T@ o; ;[I"BTo define nested classes or modules, use the functions below:;T@ o;;[I"MVALUE rb_define_class_under(VALUE outer, const char *name, VALUE super) ;TI"AVALUE rb_define_module_under(VALUE outer, const char *name) ;T;0S; ; i ;I"+Method and Singleton Method Definition;T@ o; ;[I"ATo define methods or singleton methods, use these functions:;T@ o;;[ I":void rb_define_method(VALUE klass, const char *name, ;TI"= VALUE (*func)(ANYARGS), int argc) ;TI" ;TI"Evoid rb_define_singleton_method(VALUE object, const char *name, ;TI"G VALUE (*func)(ANYARGS), int argc) ;T;0o; ;[I"JThe `argc' represents the number of the arguments to the C function, ;TI"Dwhich must be less than 17. But I doubt you'll need that many.;T@ o; ;[I"MIf `argc' is negative, it specifies the calling sequence, not number of ;TI"the arguments.;T@ o; ;[I"3If argc is -1, the function will be called as:;T@ o;;[I"2VALUE func(int argc, VALUE *argv, VALUE obj) ;T;0o; ;[I"Jwhere argc is the actual number of arguments, argv is the C array of ;TI",the arguments, and obj is the receiver.;T@ o; ;[I"KIf argc is -2, the arguments are passed in a Ruby array. The function ;TI"will be called like:;T@ o;;[I"'VALUE func(VALUE obj, VALUE args) ;T;0o; ;[I"Fwhere obj is the receiver, and args is the Ruby array containing ;TI"actual arguments.;T@ o; ;[I"FThere are some more functions to define methods. One takes an ID ;TI"Fas the name of method to be defined. See also ID or Symbol below.;T@ o;;[I"4void rb_define_method_id(VALUE klass, ID name, ;TI"@ VALUE (*func)(ANYARGS), int argc) ;T;0o; ;[I"AThere are two functions to define private/protected methods:;T@ o;;[ I"Bvoid rb_define_private_method(VALUE klass, const char *name, ;TI"E VALUE (*func)(ANYARGS), int argc) ;TI"Dvoid rb_define_protected_method(VALUE klass, const char *name, ;TI"G VALUE (*func)(ANYARGS), int argc) ;T;0o; ;[ I"CAt last, rb_define_module_function defines a module function, ;TI"<which are private AND singleton methods of the module. ;TI"HFor example, sqrt is a module function defined in the Math module. ;TI"+It can be called in the following way:;T@ o;;[I"Math.sqrt(4) ;T;0o; ;[I"or;T@ o;;[I"include Math ;TI" sqrt(4) ;T;0o; ;[I"%To define module functions, use:;T@ o;;[I"Dvoid rb_define_module_function(VALUE module, const char *name, ;TI"F VALUE (*func)(ANYARGS), int argc) ;T;0o; ;[I"KIn addition, function-like methods, which are private methods defined ;TI"0in the Kernel module, can be defined using:;T@ o;;[I"Xvoid rb_define_global_function(const char *name, VALUE (*func)(ANYARGS), int argc) ;T;0o; ;[I"'To define an alias for the method,;T@ o;;[I"Kvoid rb_define_alias(VALUE module, const char* new, const char* old); ;T;0o; ;[I"0To define a reader/writer for an attribute,;T@ o;;[I"Mvoid rb_define_attr(VALUE klass, const char *name, int read, int write) ;T;0o; ;[I"8To define and undefine the `allocate' class method,;T@ o;;[I"Ivoid rb_define_alloc_func(VALUE klass, VALUE (*func)(VALUE klass)); ;TI",void rb_undef_alloc_func(VALUE klass); ;T;0o; ;[I"Cfunc has to take the klass as the argument and return a newly ;TI"Hallocated instance. This instance should be as empty as possible, ;TI":without any expensive (including external) resources.;T@ o; ;[I"MIf you are overriding an existing method of any ancestor of your class, ;TI"you may rely on:;T@ o;;[I"6VALUE rb_call_super(int argc, const VALUE *argv) ;T;0o; ;[I"FTo achieve the receiver of the current scope (if no other way is ;TI"available), you can use:;T@ o;;[I"%VALUE rb_current_receiver(void) ;T;0S; ; i ;I"Constant Definition;T@ o; ;[I"-We have 2 functions to define constants:;T@ o;;[I"Dvoid rb_define_const(VALUE klass, const char *name, VALUE val) ;TI">void rb_define_global_const(const char *name, VALUE val) ;T;0o; ;[I"KThe former is to define a constant under specified class/module. The ;TI"+latter is to define a global constant.;T@ S; ; i;I"Use Ruby Features from C;T@ o; ;[I"BThere are several ways to invoke Ruby's features from C code.;T@ S; ; i ;I"'Evaluate Ruby Programs in a String;T@ o; ;[I"HThe easiest way to use Ruby's functionality from a C program is to ;TI"Ievaluate the string as Ruby program. This function will do the job:;T@ o;;[I"+VALUE rb_eval_string(const char *str) ;T;0o; ;[I"PEvaluation is done under the current context, thus current local variables ;TI"Hof the innermost method (which is defined by Ruby) can be accessed.;T@ o; ;[I"GNote that the evaluation can raise an exception. There is a safer ;TI"function:;T@ o;;[I"?VALUE rb_eval_string_protect(const char *str, int *state) ;T;0o; ;[I"PIt returns nil when an error occurred. Moreover, *state is zero if str was ;TI"2successfully evaluated, or nonzero otherwise.;T@ S; ; i ;I"ID or Symbol;T@ o; ;[ I"KYou can invoke methods directly, without parsing the string. First I ;TI"Fneed to explain about ID. ID is the integer number to represent ;TI"DRuby's identifiers such as variable names. The Ruby data type ;TI"Icorresponding to ID is Symbol. It can be accessed from Ruby in the ;TI" form:;T@ o;;[I":Identifier ;T;0o; ;[I"or;T@ o;;[I":"any kind of string" ;T;0o; ;[I"BYou can get the ID value from a string within C code by using;T@ o;;[I"!rb_intern(const char *name) ;TI"rb_intern_str(VALUE name) ;T;0o; ;[I"IYou can retrieve ID from Ruby object (Symbol or String) given as an ;TI"argument by using;T@ o;;[I"rb_to_id(VALUE symbol) ;TI"'rb_check_id(volatile VALUE *name) ;TI"Drb_check_id_cstr(const char *name, long len, rb_encoding *enc) ;T;0o; ;[I"KThese functions try to convert the argument to a String if it was not ;TI"Fa Symbol nor a String. The second function stores the converted ;TI"Kresult into *name, and returns 0 if the string is not a known symbol. ;TI"FAfter this function returned a non-zero value, *name is always a ;TI"FSymbol or a String, otherwise it is a String if the result is 0. ;TI"FThe third function takes NUL-terminated C string, not Ruby VALUE.;T@ o; ;[I"JYou can retrieve Symbol from Ruby object (Symbol or String) given as ;TI"an argument by using;T@ o;;[I"rb_to_symbol(VALUE name) ;TI",rb_check_symbol(volatile VALUE *namep) ;TI"Grb_check_symbol_cstr(const char *ptr, long len, rb_encoding *enc) ;T;0o; ;[I"FThese functions are similar to above functions except that these ;TI"&return a Symbol instead of an ID.;T@ o; ;[I"1You can convert C ID to Ruby Symbol by using;T@ o;;[I"VALUE ID2SYM(ID id) ;T;0o; ;[I"1and to convert Ruby Symbol object to ID, use;T@ o;;[I"ID SYM2ID(VALUE symbol) ;T;0S; ; i ;I"Invoke Ruby Method from C;T@ o; ;[I"?To invoke methods directly, you can use the function below;T@ o;;[I"9VALUE rb_funcall(VALUE recv, ID mid, int argc, ...) ;T;0o; ;[I"FThis function invokes a method on the recv, with the method name ;TI"!specified by the symbol mid.;T@ S; ; i ;I"*Accessing the Variables and Constants;T@ o; ;[I"HYou can access class variables and instance variables using access ;TI"Cfunctions. Also, global variables can be shared between both ;TI"Denvironments. There's no way to access Ruby's local variables.;T@ o; ;[I"AThe functions to access/modify instance variables are below:;T@ o;;[I")VALUE rb_ivar_get(VALUE obj, ID id) ;TI"4VALUE rb_ivar_set(VALUE obj, ID id, VALUE val) ;T;0o; ;[I"Bid must be the symbol, which can be retrieved by rb_intern().;T@ o; ;[I"1To access the constants of the class/module:;T@ o;;[I"*VALUE rb_const_get(VALUE obj, ID id) ;T;0o; ;[I"(See also Constant Definition above.;T@ S; ; i;I"+Information Sharing Between Ruby and C;T@ S; ; i;I"/Ruby Constants That Can Be Accessed From C;T@ o; ;[I"As stated in section 1.3, ;TI"9the following Ruby constants can be referred from C.;T@ o;;;;[o;;[I"Qtrue ;TI"Qfalse ;T;[o; ;[I"9Boolean values. Qfalse is false in C also (i.e. 0).;T@ o;;[I" Qnil ;T;[o; ;[I"Ruby nil in C scope.;T@ S; ; i;I"/Global Variables Shared Between C and Ruby;T@ o; ;[I"PInformation can be shared between the two environments using shared global ;TI"Dvariables. To define them, you can use functions listed below:;T@ o;;[I";void rb_define_variable(const char *name, VALUE *var) ;T;0o; ;[I"NThis function defines the variable which is shared by both environments. ;TI"JThe value of the global variable pointed to by `var' can be accessed ;TI"1through Ruby's global variable named `name'.;T@ o; ;[I"IYou can define read-only (from Ruby, of course) variables using the ;TI"function below.;T@ o;;[I"Dvoid rb_define_readonly_variable(const char *name, VALUE *var) ;T;0o; ;[I"JYou can define hooked variables. The accessor functions (getter and ;TI":setter) are called on access to the hooked variables.;T@ o;;[I"Bvoid rb_define_hooked_variable(const char *name, VALUE *var, ;TI"I VALUE (*getter)(), void (*setter)()) ;T;0o; ;[I"JIf you need to supply either setter or getter, just supply 0 for the ;TI"Lhook you don't need. If both hooks are 0, rb_define_hooked_variable() ;TI"*works just like rb_define_variable().;T@ o; ;[I"FThe prototypes of the getter and setter functions are as follows:;T@ o;;[I")VALUE (*getter)(ID id, VALUE *var); ;TI"3void (*setter)(VALUE val, ID id, VALUE *var); ;T;0o; ;[I"JAlso you can define a Ruby global variable without a corresponding C ;TI"Hvariable. The value of the variable will be set/get only by hooks.;T@ o;;[I"7void rb_define_virtual_variable(const char *name, ;TI"J VALUE (*getter)(), void (*setter)()) ;T;0o; ;[I"FThe prototypes of the getter and setter functions are as follows:;T@ o;;[I"VALUE (*getter)(ID id); ;TI"'void (*setter)(VALUE val, ID id); ;T;0S; ; i;I"*Encapsulate C Data into a Ruby Object;T@ o; ;[ I"GSometimes you need to expose your struct in the C world as a Ruby ;TI" object. ;TI"EIn a situation like this, making use of the TypedData_XXX macro ;TI"Kfamily, the pointer to the struct and the Ruby object can be mutually ;TI"converted.;T@ S; ; i ;I"C struct to Ruby object;T@ o; ;[I"HYou can convert sval, a pointer to your struct, into a Ruby object ;TI"with the next macro.;T@ o;;[I"3TypedData_Wrap_Struct(klass, data_type, sval) ;T;0o; ;[I"FTypedData_Wrap_Struct() returns a created Ruby object as a VALUE.;T@ o; ;[I"5The klass argument is the class for the object. ;TI"Fdata_type is a pointer to a const rb_data_type_t which describes ;TI"'how Ruby should manage the struct.;T@ o; ;[I"FIt is recommended that klass derives from a special class called ;TI"CData (rb_cData) but not from Object or other ordinal classes. ;TI"@If it doesn't, you have to call rb_undef_alloc_func(klass).;T@ o; ;[I"Erb_data_type_t is defined like this. Let's take a look at each ;TI"member of the struct.;T@ o;;[I""struct rb_data_type_struct { ;TI"+ const char *wrap_struct_name; ;TI" struct { ;TI"+ void (*dmark)(void*); ;TI"+ void (*dfree)(void*); ;TI"4 size_t (*dsize)(const void *); ;TI"( void *reserved[2]; ;TI" } function; ;TI"+ const rb_data_type_t *parent; ;TI" void *data; ;TI" VALUE flags; ;TI"}; ;T;0o; ;[ I"Gwrap_struct_name is an identifier of this instance of the struct. ;TI"BIt is basically used for collecting and emitting statistics. ;TI"GSo the identifier must be unique in the process, but doesn't need ;TI"+to be valid as a C or Ruby identifier.;T@ o; ;[I"HThese dmark / dfree functions are invoked during GC execution. No ;TI"Gobject allocations are allowed during it, so do not allocate ruby ;TI"objects inside them.;T@ o; ;[I"Idmark is a function to mark Ruby objects referred from your struct. ;TI"EIt must mark all references from your struct with rb_gc_mark or ;TI"5its family if your struct keeps such references.;T@ o; ;[I"9dfree is a function to free the pointer allocation. ;TI"3If this is -1, the pointer will be just freed.;T@ o; ;[ I"Adsize calculates memory consumption in bytes by the struct. ;TI"0Its parameter is a pointer to your struct. ;TI"IYou can pass 0 as dsize if it is hard to implement such a function. ;TI",But it is still recommended to avoid 0.;T@ o; ;[I"1You have to fill reserved and parent with 0.;T@ o; ;[I"?You can fill "data" with an arbitrary value for your use. ;TI"'Ruby does nothing with the member.;T@ o; ;[I"9flags is a bitwise-OR of the following flag values. ;TI"ISince they require deep understanding of garbage collector in Ruby, ;TI"5you can just set 0 to flags if you are not sure.;T@ o;;;;[o;;[I"!RUBY_TYPED_FREE_IMMEDIATELY ;T;[ o; ;[ I"FThis flag makes the garbage collector immediately invoke dfree() ;TI"1during GC when it need to free your struct. ;TI"AYou can specify this flag if the dfree never unlocks Ruby's ;TI"internal lock (GVL).;T@ o; ;[I"@If this flag is not set, Ruby defers invokation of dfree() ;TI"8and invokes dfree() at the same time as finalizers.;T@ o;;[I"RUBY_TYPED_WB_PROTECTED ;T;[o; ;[I"IIt shows that implementation of the object supports write barriers. ;TI"GIf this flag is set, Ruby is better able to do garbage collection ;TI"of the object.;T@ o; ;[I"DWhen it is set, however, you are responsible for putting write ;TI"Bbarriers in all implementations of methods of that object as ;TI";appropriate. Otherwise Ruby might crash while running.;T@ o; ;[I"DMore about write barriers can be found in "Generational GC" in ;TI"Appendix D.;T@ o; ;[I"9You can allocate and wrap the structure in one step.;T@ o;;[I"9TypedData_Make_Struct(klass, type, data_type, sval) ;T;0o; ;[I"JThis macro returns an allocated Data object, wrapping the pointer to ;TI"Dthe structure, which is also allocated. This macro works like:;T@ o;;[I"J(sval = ZALLOC(type), TypedData_Wrap_Struct(klass, data_type, sval)) ;T;0o; ;[I"CArguments klass and data_type work like their counterparts in ;TI"ITypedData_Wrap_Struct(). A pointer to the allocated structure will ;TI"Jbe assigned to sval, which should be a pointer of the type specified.;T@ S; ; i ;I"Ruby object to C struct;T@ o; ;[I"CTo retrieve the C pointer from the Data object, use the macro ;TI"Data_Get_Struct().;T@ o;;[I"7TypedData_Get_Struct(obj, type, &data_type, sval) ;T;0o; ;[I"FA pointer to the structure will be assigned to the variable sval.;T@ o; ;[I"'See the example below for details.;T@ S; ; i;I")Example - Creating the dbm Extension;T@ o; ;[I"IOK, here's the example of making an extension library. This is the ;TI"Hextension to access DBMs. The full source is included in the ext/ ;TI")directory in the Ruby's source tree.;T@ S; ; i;I"Make the Directory;T@ o;;[I"% mkdir ext/dbm ;T;0o; ;[I"DMake a directory for the extension library under ext directory.;T@ S; ; i;I"Design the Library;T@ o; ;[I"?You need to design the library features, before making it.;T@ S; ; i;I"Write the C Code;T@ o; ;[ I"KYou need to write C code for your extension library. If your library ;TI"Hhas only one source file, choosing ``LIBRARY.c'' as a file name is ;TI"Mpreferred. On the other hand, in case your library has multiple source ;TI"Kfiles, avoid choosing ``LIBRARY.c'' for a file name. It may conflict ;TI"@with an intermediate file ``LIBRARY.o'' on some platforms. ;TI"GNote that some functions in mkmf library described below generate ;TI"Ia file ``conftest.c'' for checking with compilation. You shouldn't ;TI"6choose ``conftest.c'' as a name of a source file.;T@ o; ;[I"KRuby will execute the initializing function named ``Init_LIBRARY'' in ;TI"Mthe library. For example, ``Init_dbm()'' will be executed when loading ;TI"the library.;T@ o; ;[I"4Here's the example of an initializing function.;T@ o;;[I" void ;TI"Init_dbm(void) ;TI"{ ;TI" /* define DBM class */ ;TI": VALUE cDBM = rb_define_class("DBM", rb_cObject); ;TI". /* DBM includes Enumerable module */ ;TI"2 rb_include_module(cDBM, rb_mEnumerable); ;TI" ;TI"N /* DBM has class method open(): arguments are received as C array */ ;TI"D rb_define_singleton_method(cDBM, "open", fdbm_s_open, -1); ;TI" ;TI"4 /* DBM instance method close(): no args */ ;TI"9 rb_define_method(cDBM, "close", fdbm_close, 0); ;TI"2 /* DBM instance method []: 1 argument */ ;TI"6 rb_define_method(cDBM, "[]", fdbm_fetch, 1); ;TI" ;TI" /* ... */ ;TI" ;TI"< /* ID for a instance variable to store DBM data */ ;TI"$ id_dbm = rb_intern("dbm"); ;TI"} ;T;0o; ;[I"GThe dbm extension wraps the dbm struct in the C environment using ;TI"TypedData_Make_Struct.;T@ o;;[I"struct dbmdata { ;TI" int di_size; ;TI" DBM *di_dbm; ;TI"}; ;TI" ;TI".static const rb_data_type_t dbm_type = { ;TI" "dbm", ;TI"& {0, free_dbm, memsize_dbm,}, ;TI" 0, 0, ;TI"& RUBY_TYPED_FREE_IMMEDIATELY, ;TI"}; ;TI" ;TI"Jobj = TypedData_Make_Struct(klass, struct dbmdata, &dbm_type, dbmp); ;T;0o; ;[I"IThis code wraps the dbmdata structure into a Ruby object. We avoid ;TI"Gwrapping DBM* directly, because we want to cache size information.;T@ o; ;[I"ITo retrieve the dbmdata structure from a Ruby object, we define the ;TI"following macro:;T@ o;;[ I"%#define GetDBM(obj, dbmp) do {\ ;TI"J TypedData_Get_Struct((obj), struct dbmdata, &dbm_type, (dbmp));\ ;TI") if ((dbmp) == 0) closed_dbm();\ ;TI"1 if ((dbmp)->di_dbm == 0) closed_dbm();\ ;TI"} while (0) ;T;0o; ;[I"KThis sort of complicated macro does the retrieving and close checking ;TI"for the DBM.;T@ o; ;[I"GThere are three kinds of way to receive method arguments. First, ;TI"Jmethods with a fixed number of arguments receive arguments like this:;T@ o;;[ I"static VALUE ;TI"*fdbm_delete(VALUE obj, VALUE keystr) ;TI"{ ;TI" /* ... */ ;TI"} ;T;0o; ;[I"HThe first argument of the C function is the self, the rest are the ;TI"arguments to the method.;T@ o; ;[I"CSecond, methods with an arbitrary number of arguments receive ;TI"arguments like this:;T@ o;;[I"static VALUE ;TI"5fdbm_s_open(int argc, VALUE *argv, VALUE klass) ;TI"{ ;TI" /* ... */ ;TI"C if (rb_scan_args(argc, argv, "11", &file, &vmode) == 1) { ;TI"7 mode = 0666; /* default value */ ;TI" } ;TI" /* ... */ ;TI"} ;T;0o; ;[I"FThe first argument is the number of method arguments, the second ;TI"Dargument is the C array of the method arguments, and the third ;TI",argument is the receiver of the method.;T@ o; ;[ I"GYou can use the function rb_scan_args() to check and retrieve the ;TI"Farguments. The third argument is a string that specifies how to ;TI"Ecapture method arguments and assign them to the following VALUE ;TI"references.;T@ o; ;[I"KYou can just check the argument number with rb_check_arity(), this is ;TI"Ahandy in the case you want to treat the arguments as a list.;T@ o; ;[I"LThe following is an example of a method that takes arguments by Ruby's ;TI"array:;T@ o;;[ I"static VALUE ;TI"1thread_initialize(VALUE thread, VALUE args) ;TI"{ ;TI" /* ... */ ;TI"} ;T;0o; ;[I"JThe first argument is the receiver, the second one is the Ruby array ;TI"0which contains the arguments to the method.;T@ o; ;[I"Y<b>Notice</b>: GC should know about global variables which refer to Ruby's objects, ;TI"Ibut are not exported to the Ruby world. You need to protect them by;T@ o;;[I")void rb_global_variable(VALUE *var) ;T;0S; ; i;I"Prepare extconf.rb;T@ o; ;[I"JIf the file named extconf.rb exists, it will be executed to generate ;TI"Makefile.;T@ o; ;[I"Jextconf.rb is the file for checking compilation conditions etc. You ;TI"need to put;T@ o;;[I"require 'mkmf' ;T;0o; ;[I"Gat the top of the file. You can use the functions below to check ;TI"various conditions.;T@ o;;[I"Ihave_macro(macro[, headers[, opt]]): check whether macro is defined ;TI"chave_library(lib[, func[, headers[, opt]]]): check whether library containing function exists ;TI"@find_library(lib[, func, *paths]): find library from paths ;TI"Ehave_func(func[, headers[, opt]): check whether function exists ;TI"Dhave_var(var[, headers[, opt]]): check whether variable exists ;TI"Phave_header(header[, preheaders[, opt]]): check whether header file exists ;TI"9find_header(header, *paths): find header from paths ;TI"Fhave_framework(fw): check whether framework exists (for MacOS X) ;TI"Yhave_struct_member(type, member[, headers[, opt]]): check whether struct has member ;TI"Bhave_type(type[, headers[, opt]]): check whether type exists ;TI"Jfind_type(type, opt, *headers): check whether type exists in headers ;TI"Lhave_const(const[, headers[, opt]]): check whether constant is defined ;TI"?check_sizeof(type[, headers[, opts]]): check size of type ;TI"Icheck_signedness(type[, headers[, opts]]): check signedness of type ;TI"Mconvertible_int(type[, headers[, opts]]): find convertible integer type ;TI"=find_executable(bin[, path]): find executable file path ;TI"7create_header(header): generate configured header ;TI"Acreate_makefile(target[, target_prefix]): generate Makefile ;T;0o; ;[I"@See MakeMakefile for full documentation of these functions.;T@ o; ;[I"?The value of the variables below will affect the Makefile.;T@ o;;[ I"<$CFLAGS: included in CFLAGS make variable (such as -O) ;TI"D$CPPFLAGS: included in CPPFLAGS make variable (such as -I, -D) ;TI">$LDFLAGS: included in LDFLAGS make variable (such as -L) ;TI"&$objs: list of object file names ;T;0o; ;[I"MNormally, the object files list is automatically generated by searching ;TI"Ksource files, but you must define them explicitly if any sources will ;TI"!be generated while building.;T@ o; ;[I"FIf a compilation condition is not fulfilled, you should not call ;TI"P``create_makefile''. The Makefile will not be generated, compilation will ;TI"not be done.;T@ S; ; i;I"Prepare Depend (Optional);T@ o; ;[I"IIf the file named depend exists, Makefile will include that file to ;TI"<check dependencies. You can make this file by invoking;T@ o;;[I"% gcc -MM *.c > depend ;T;0o; ;[I" It's harmless. Prepare it.;T@ S; ; i;I"Generate Makefile;T@ o; ;[I"$Try generating the Makefile by:;T@ o;;[I"ruby extconf.rb ;T;0o; ;[I"DIf the library should be installed under vendor_ruby directory ;TI"Dinstead of site_ruby directory, use --vendor option as follows.;T@ o;;[I"ruby extconf.rb --vendor ;T;0o; ;[I"MYou don't need this step if you put the extension library under the ext ;TI"Jdirectory of the ruby source tree. In that case, compilation of the ;TI"+interpreter will do this step for you.;T@ S; ; i;I" Run make;T@ o; ;[I" Type;T@ o;;[I" make ;T;0o; ;[I"Mto compile your extension. You don't need this step either if you have ;TI"Oput the extension library under the ext directory of the ruby source tree.;T@ S; ; i;I" Debug;T@ o; ;[I"GYou may need to rb_debug the extension. Extensions can be linked ;TI"Kstatically by adding the directory name in the ext/Setup file so that ;TI"5you can inspect the extension with the debugger.;T@ S; ; i;I"-Done! Now You Have the Extension Library;T@ o; ;[I"IYou can do anything you want with your library. The author of Ruby ;TI"Mwill not claim any restrictions on your code depending on the Ruby API. ;TI"?Feel free to use, modify, distribute or sell your program.;T@ S; ; i;I"+Appendix A. Ruby Source Files Overview;T@ S; ; i;I"Ruby Language Core;T@ o;;;;[o;;[I"class.c ;T;[o; ;[I"classes and modules;To;;[I"error.c ;T;[o; ;[I".exception classes and exception mechanism;To;;[I"gc.c ;T;[o; ;[I"memory management;To;;[I"load.c ;T;[o; ;[I"library loading;To;;[I"object.c ;T;[o; ;[I"objects;To;;[I"variable.c ;T;[o; ;[I"variables and constants;T@ S; ; i;I"Ruby Syntax Parser;T@ o;;;;[ o;;[I"parse.y ;T;[o; ;[I"grammar definition;To;;[I"parse.c ;T;[o; ;[I")automatically generated from parse.y;To;;[I"defs/keywords ;T;[o; ;[I"reserved keywords;To;;[I"lex.c ;T;[o; ;[I"*automatically generated from keywords;T@ S; ; i;I"!Ruby Evaluator (a.k.a. YARV);T@ o;;[I"compile.c ;TI"eval.c ;TI"eval_error.c ;TI"eval_jump.c ;TI"eval_safe.c ;TI"9insns.def : definition of VM instructions ;TI"6iseq.c : implementation of VM::ISeq ;TI"Cthread.c : thread management and context switching ;TI"1thread_win32.c : thread implementation ;TI"!thread_pthread.c : ditto ;TI" vm.c ;TI"vm_dump.c ;TI"vm_eval.c ;TI"vm_exec.c ;TI"vm_insnhelper.c ;TI"vm_method.c ;TI" ;TI"8defs/opt_insns_unif.def : instruction unification ;TI"=defs/opt_operand.def : definitions for optimization ;TI" ;TI"8 -> insn*.inc : automatically generated ;TI"8 -> opt*.inc : automatically generated ;TI"8 -> vm.inc : automatically generated ;T;0S; ; i;I"*Regular Expression Engine (Oniguruma);T@ o;;[I" regex.c ;TI"regcomp.c ;TI"regenc.c ;TI"regerror.c ;TI"regexec.c ;TI"regparse.c ;TI"regsyntax.c ;T;0S; ; i;I"Utility Functions;T@ o;;;;[ o;;[I"debug.c ;T;[o; ;[I"!debug symbols for C debugger;To;;[I"dln.c ;T;[o; ;[I"dynamic loading;To;;[I"st.c ;T;[o; ;[I"general purpose hash table;To;;[I"strftime.c ;T;[o; ;[I"formatting times;To;;[I"util.c ;T;[o; ;[I"misc utilities;T@ S; ; i;I"$Ruby Interpreter Implementation;T@ o;;[I"dmyext.c ;TI"dmydln.c ;TI"dmyencoding.c ;TI" id.c ;TI" inits.c ;TI"main.c ;TI"ruby.c ;TI"version.c ;TI" ;TI"gem_prelude.rb ;TI"prelude.rb ;T;0S; ; i;I"Class Library;T@ o;;;;[!o;;[I"array.c ;T;[o; ;[I" Array;To;;[I"bignum.c ;T;[o; ;[I"Bignum;To;;[I"compar.c ;T;[o; ;[I"Comparable;To;;[I"complex.c ;T;[o; ;[I"Complex;To;;[I"cont.c ;T;[o; ;[I"Fiber, Continuation;To;;[I"dir.c ;T;[o; ;[I"Dir;To;;[I"enum.c ;T;[o; ;[I"Enumerable;To;;[I"enumerator.c ;T;[o; ;[I"Enumerator;To;;[I"file.c ;T;[o; ;[I" File;To;;[I"hash.c ;T;[o; ;[I" Hash;To;;[I"io.c ;T;[o; ;[I"IO;To;;[I"marshal.c ;T;[o; ;[I"Marshal;To;;[I"math.c ;T;[o; ;[I" Math;To;;[I"numeric.c ;T;[o; ;[I"$Numeric, Integer, Fixnum, Float;To;;[I"pack.c ;T;[o; ;[I"Array#pack, String#unpack;To;;[I"proc.c ;T;[o; ;[I"Binding, Proc;To;;[I"process.c ;T;[o; ;[I"Process;To;;[I"random.c ;T;[o; ;[I"random number;To;;[I"range.c ;T;[o; ;[I" Range;To;;[I"rational.c ;T;[o; ;[I" Rational;To;;[I"re.c ;T;[o; ;[I"Regexp, MatchData;To;;[I"signal.c ;T;[o; ;[I"Signal;To;;[I"sprintf.c ;T;[o; ;[I"String#sprintf;To;;[I"string.c ;T;[o; ;[I"String;To;;[I"struct.c ;T;[o; ;[I"Struct;To;;[I"time.c ;T;[o; ;[I" Time;T@ o;;[I"defs/known_errors.def ;T;[o; ;[I"Errno::* exception classes;To;;[I"-> known_errors.inc ;T;[o; ;[I"automatically generated;T@ S; ; i;I"Multilingualization;T@ o;;;;[ o;;[I"encoding.c ;T;[o; ;[I" Encoding;To;;[I"transcode.c ;T;[o; ;[I"Encoding::Converter;To;;[I"enc/*.c ;T;[o; ;[I"encoding classes;To;;[I"enc/trans/* ;T;[o; ;[I"codepoint mapping tables;T@ S; ; i;I"&goruby Interpreter Implementation;T@ o;;[I"goruby.c ;TI"6golf_prelude.rb : goruby specific libraries. ;TI"3 -> golf_prelude.c : automatically generated ;T;0S; ; i;I"-Appendix B. Ruby Extension API Reference;T@ S; ; i;I" Types;T@ o;;;;[o;;[I"VALUE ;T;[o; ;[I"MThe type for the Ruby object. Actual structures are defined in ruby.h, ;TI"Jsuch as struct RString, etc. To refer the values in structures, use ;TI"&casting macros like RSTRING(obj).;T@ S; ; i;I"Variables and Constants;T@ o;;;;[o;;[I" Qnil ;T;[o; ;[I"nil object;T@ o;;[I"Qtrue ;T;[o; ;[I"%true object (default true value);T@ o;;[I"Qfalse ;T;[o; ;[I"false object;T@ S; ; i;I"C Pointer Wrapping;T@ o;;;;[o;;[I"OData_Wrap_Struct(VALUE klass, void (*mark)(), void (*free)(), void *sval) ;T;[o; ;[ I"MWrap a C pointer into a Ruby object. If object has references to other ;TI"KRuby objects, they should be marked by using the mark function during ;TI"Kthe GC process. Otherwise, mark should be 0. When this object is no ;TI"Hlonger referred by anywhere, the pointer will be discarded by free ;TI"function.;T@ o;;[I"5Data_Make_Struct(klass, type, mark, free, sval) ;T;[o; ;[I"LThis macro allocates memory using malloc(), assigns it to the variable ;TI"Ksval, and returns the DATA encapsulating the pointer to memory region.;T@ o;;[I"'Data_Get_Struct(data, type, sval) ;T;[o; ;[I"IThis macro retrieves the pointer value from DATA, and assigns it to ;TI"the variable sval.;T@ S; ; i;I"Checking Data Types;T@ o;;;;[ o;;[I"RB_TYPE_P(value, type) ;T;[o; ;[I"9Is +value+ an internal type (T_NIL, T_FIXNUM, etc.)?;T@ o;;[I"TYPE(value) ;T;[o; ;[I"*Internal type (T_NIL, T_FIXNUM, etc.);T@ o;;[I"FIXNUM_P(value) ;T;[o; ;[I"Is +value+ a Fixnum?;T@ o;;[I"NIL_P(value) ;T;[o; ;[I"Is +value+ nil?;T@ o;;[I"RB_INTEGER_TYPE_P(value) ;T;[o; ;[I"Is +value+ an Integer?;T@ o;;[I"RB_FLOAT_TYPE_P(value) ;T;[o; ;[I"Is +value+ a Float?;T@ o;;[I",void Check_Type(VALUE value, int type) ;T;[o; ;[I"JEnsures +value+ is of the given internal +type+ or raises a TypeError;T@ o;;[I"SafeStringValue(value) ;T;[o; ;[I"7Checks that +value+ is a String and is not tainted;T@ S; ; i;I"Data Type Conversion;T@ o;;;;[o;;[I" FIX2INT(value), INT2FIX(i) ;T;[o; ;[I"Fixnum <-> integer;T@ o;;[I""FIX2LONG(value), LONG2FIX(l) ;T;[o; ;[I"Fixnum <-> long;T@ o;;[I" NUM2INT(value), INT2NUM(i) ;T;[o; ;[I"Numeric <-> integer;T@ o;;[I"#NUM2UINT(value), UINT2NUM(ui) ;T;[o; ;[I"!Numeric <-> unsigned integer;T@ o;;[I""NUM2LONG(value), LONG2NUM(l) ;T;[o; ;[I"Numeric <-> long;T@ o;;[I"%NUM2ULONG(value), ULONG2NUM(ul) ;T;[o; ;[I"Numeric <-> unsigned long;T@ o;;[I"NUM2LL(value), LL2NUM(ll) ;T;[o; ;[I"Numeric <-> long long;T@ o;;[I""NUM2ULL(value), ULL2NUM(ull) ;T;[o; ;[I"#Numeric <-> unsigned long long;T@ o;;[I"$NUM2OFFT(value), OFFT2NUM(off) ;T;[o; ;[I"Numeric <-> off_t;T@ o;;[I"'NUM2SIZET(value), SIZET2NUM(size) ;T;[o; ;[I"Numeric <-> size_t;T@ o;;[I"*NUM2SSIZET(value), SSIZET2NUM(ssize) ;T;[o; ;[I"Numeric <-> ssize_t;T@ o;;[I"|rb_integer_pack(value, words, numwords, wordsize, nails, flags), rb_integer_unpack(words, numwords, wordsize, nails, flags) ;T;[o; ;[I".Numeric <-> Arbitrary size integer buffer;T@ o;;[I"NUM2DBL(value) ;T;[o; ;[I"Numeric -> double;T@ o;;[I"rb_float_new(f) ;T;[o; ;[I"double -> Float;T@ o;;[I"RSTRING_LEN(str) ;T;[o; ;[I"-String -> length of String data in bytes;T@ o;;[I"RSTRING_PTR(str) ;T;[o; ;[I"&String -> pointer to String data ;TI";Note that the result pointer may not be NUL-terminated;T@ o;;[I"StringValue(value) ;T;[o; ;[I"#Object with \#to_str -> String;T@ o;;[I"StringValuePtr(value) ;T;[o; ;[I"3Object with \#to_str -> pointer to String data;T@ o;;[I"StringValueCStr(value) ;T;[o; ;[I"FObject with \#to_str -> pointer to String data without NUL bytes ;TI"<It is guaranteed that the result data is NUL-terminated;T@ o;;[I"rb_str_new2(s) ;T;[o; ;[I"char * -> String;T@ S; ; i;I"!Defining Classes and Modules;T@ o;;;;[o;;[I":VALUE rb_define_class(const char *name, VALUE super) ;T;[o; ;[I"5Defines a new Ruby class as a subclass of super.;T@ o;;[I"NVALUE rb_define_class_under(VALUE module, const char *name, VALUE super) ;T;[o; ;[I"ICreates a new Ruby class as a subclass of super, under the module's ;TI"namespace.;T@ o;;[I".VALUE rb_define_module(const char *name) ;T;[o; ;[I"Defines a new Ruby module.;T@ o;;[I"BVALUE rb_define_module_under(VALUE module, const char *name) ;T;[o; ;[I"<Defines a new Ruby module under the module's namespace.;T@ o;;[I"7void rb_include_module(VALUE klass, VALUE module) ;T;[o; ;[I"MIncludes module into class. If class already includes it, just ignored.;T@ o;;[I"7void rb_extend_object(VALUE object, VALUE module) ;T;[o; ;[I"4Extend the object with the module's attributes.;T@ S; ; i;I"Defining Global Variables;T@ o;;;;[ o;;[I";void rb_define_variable(const char *name, VALUE *var) ;T;[o; ;[I"LDefines a global variable which is shared between C and Ruby. If name ;TI"Icontains a character which is not allowed to be part of the symbol, ;TI")it can't be seen from Ruby programs.;T@ o;;[I"Dvoid rb_define_readonly_variable(const char *name, VALUE *var) ;T;[o; ;[I";Defines a read-only global variable. Works just like ;TI"Drb_define_variable(), except the defined variable is read-only.;T@ o;;[I"\void rb_define_virtual_variable(const char *name, VALUE (*getter)(), void (*setter)()) ;T;[ o; ;[ I"JDefines a virtual variable, whose behavior is defined by a pair of C ;TI"Dfunctions. The getter function is called when the variable is ;TI"Nreferenced. The setter function is called when the variable is set to a ;TI";value. The prototype for getter/setter functions are:;T@ o;;[I"VALUE getter(ID id) ;TI"#void setter(VALUE val, ID id) ;T;0o; ;[I">The getter function must return the value for the access.;T@ o;;[I"gvoid rb_define_hooked_variable(const char *name, VALUE *var, VALUE (*getter)(), void (*setter)()) ;T;[o; ;[I"JDefines hooked variable. It's a virtual variable with a C variable. ;TI"The getter is called as;T@ o;;[I"%VALUE getter(ID id, VALUE *var) ;T;0o; ;[I"4returning a new value. The setter is called as;T@ o;;[I"/void setter(VALUE val, ID id, VALUE *var) ;T;0o;;[I")void rb_global_variable(VALUE *var) ;T;[o; ;[I"IGC requires C global variables which hold Ruby values to be marked. ;TI"<rb_global_variable tells GC to protect these variables.;T@ S; ; i;I"Constant Definition;T@ o;;;;[o;;[I"Dvoid rb_define_const(VALUE klass, const char *name, VALUE val) ;T;[o; ;[I"3Defines a new constant under the class/module.;T@ o;;[I">void rb_define_global_const(const char *name, VALUE val) ;T;[o; ;[I"9Defines a global constant. This is just the same as;T@ o;;[I",rb_define_const(rb_cObject, name, val) ;T;0S; ; i;I"Method Definition;T@ o;;;;[o;;[I"Wrb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc) ;T;[o; ;[ I"JDefines a method for the class. func is the function pointer. argc ;TI"Kis the number of arguments. if argc is -1, the function will receive ;TI"J3 arguments: argc, argv, and self. if argc is -2, the function will ;TI"Greceive 2 arguments, self and args, where args is a Ruby array of ;TI"the method arguments.;T@ o;;[I"_rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc) ;T;[o; ;[I"DDefines a private method for the class. Arguments are same as ;TI"rb_define_method().;T@ o;;[I"arb_define_singleton_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc) ;T;[o; ;[I"KDefines a singleton method. Arguments are same as rb_define_method().;T@ o;;[I"0rb_check_arity(int argc, int min, int max) ;T;[o; ;[I"JCheck the number of arguments, argc is in the range of min..max. If ;TI"Imax is UNLIMITED_ARGUMENTS, upper bound is not checked. If argc is ;TI"4out of bounds, an ArgumentError will be raised.;T@ o;;[I"?rb_scan_args(int argc, VALUE *argv, const char *fmt, ...) ;T;[o; ;[I"DRetrieve argument from argc and argv to given VALUE references ;TI"Jaccording to the format string. The format can be described in ABNF ;TI"as follows:;T@ o;;[)I"Nscan-arg-spec := param-arg-spec [option-hash-arg-spec] [block-arg-spec] ;TI" ;TI"Fparam-arg-spec := pre-arg-spec [post-arg-spec] / post-arg-spec / ;TI"- pre-opt-post-arg-spec ;TI"Lpre-arg-spec := num-of-leading-mandatory-args [num-of-optional-args] ;TI"4post-arg-spec := sym-for-variable-length-args ;TI"8 [num-of-trailing-mandatory-args] ;TI"Qpre-opt-post-arg-spec := num-of-leading-mandatory-args num-of-optional-args ;TI"= num-of-trailing-mandatory-args ;TI"5option-hash-arg-spec := sym-for-option-hash-arg ;TI")block-arg-spec := sym-for-block-arg ;TI" ;TI"Enum-of-leading-mandatory-args := DIGIT ; The number of leading ;TI"C ; mandatory arguments ;TI"Fnum-of-optional-args := DIGIT ; The number of optional ;TI"9 ; arguments ;TI"Gsym-for-variable-length-args := "*" ; Indicates that variable ;TI"D ; length arguments are ;TI"H ; captured as a ruby array ;TI"Fnum-of-trailing-mandatory-args := DIGIT ; The number of trailing ;TI"C ; mandatory arguments ;TI"Hsym-for-option-hash-arg := ":" ; Indicates that an option ;TI"L ; hash is captured if the last ;TI"L ; argument is a hash or can be ;TI"H ; converted to a hash with ;TI"H ; #to_hash. When the last ;TI"F ; argument is nil, it is ;TI"E ; captured if it is not ;TI"G ; ambiguous to take it as ;TI"K ; empty option hash; i.e. '*' ;TI"D ; is not specified and ;TI"H ; arguments are given more ;TI"@ ; than sufficient. ;TI"Jsym-for-block-arg := "&" ; Indicates that an iterator ;TI"K ; block should be captured if ;TI"5 ; given ;T;0o; ;[I"CFor example, "12" means that the method requires at least one ;TI"Kargument, and at most receives three (1+2) arguments. So, the format ;TI"Kstring must be followed by three variable references, which are to be ;TI"Kassigned to captured arguments. For omitted arguments, variables are ;TI"Kset to Qnil. NULL can be put in place of a variable reference, which ;TI"Imeans the corresponding captured argument(s) should be just dropped.;T@ o; ;[I"IThe number of given arguments, excluding an option hash or iterator ;TI"block, is returned.;T@ o;;[I"gint rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values) ;T;[ o; ;[I"LRetrieves argument VALUEs bound to keywords, which directed by +table+ ;TI"Iinto +values+, deleting retrieved entries from +keyword_hash+ along ;TI"Fthe way. First +required+ number of IDs referred by +table+ are ;TI"?mandatory, and succeeding +optional+ (- +optional+ - 1 if ;TI"?+optional+ is negative) number of IDs are optional. If a ;TI"Gmandatory key is not contained in +keyword_hash+, raises "missing ;TI"Ekeyword" +ArgumentError+. If an optional key is not present in ;TI"O+keyword_hash+, the corresponding element in +values+ is set to +Qundef+. ;TI"NIf +optional+ is negative, rest of +keyword_hash+ are ignored, otherwise ;TI".raises "unknown keyword" +ArgumentError+.;T@ o; ;[ I"JBe warned, handling keyword arguments in the C API is less efficient ;TI"Gthan handling them in Ruby. Consider using a Ruby wrapper method ;TI"&around a non-keyword C function. ;TI"1ref: https://bugs.ruby-lang.org/issues/11339;T@ o;;[I"5VALUE rb_extract_keywords(VALUE *original_hash) ;T;[o; ;[ I"FExtracts pairs whose key is a symbol into a new hash from a hash ;TI"Hobject referred by +original_hash+. If the original hash contains ;TI"Lnon-symbol keys, then they are copied to another hash and the new hash ;TI"9is stored through +original_hash+, else 0 is stored.;T@ S; ; i;I"Invoking Ruby method;T@ o;;;;[ o;;[I"9VALUE rb_funcall(VALUE recv, ID mid, int narg, ...) ;T;[o; ;[I"MInvokes a method. To retrieve mid from a method name, use rb_intern(). ;TI"1Able to call even private/protected methods.;T@ o;;[I"BVALUE rb_funcall2(VALUE recv, ID mid, int argc, VALUE *argv) ;TI"BVALUE rb_funcallv(VALUE recv, ID mid, int argc, VALUE *argv) ;T;[o; ;[I"@Invokes a method, passing arguments as an array of values. ;TI"1Able to call even private/protected methods.;T@ o;;[I"IVALUE rb_funcallv_public(VALUE recv, ID mid, int argc, VALUE *argv) ;T;[o; ;[I"@Invokes a method, passing arguments as an array of values. ;TI"&Able to call only public methods.;T@ o;;[I"+VALUE rb_eval_string(const char *str) ;T;[o; ;[I"8Compiles and executes the string as a Ruby program.;T@ o;;[I"$ID rb_intern(const char *name) ;T;[o; ;[I"*Returns ID corresponding to the name.;T@ o;;[I"char *rb_id2name(ID id) ;T;[o; ;[I"'Returns the name corresponding ID.;T@ o;;[I"&char *rb_class2name(VALUE klass) ;T;[o; ;[I"#Returns the name of the class.;T@ o;;[I")int rb_respond_to(VALUE obj, ID id) ;T;[o; ;[I"HReturns true if the object responds to the message specified by id.;T@ S; ; i;I"Instance Variables;T@ o;;;;[o;;[I"2VALUE rb_iv_get(VALUE obj, const char *name) ;T;[o; ;[I"FRetrieve the value of the instance variable. If the name is not ;TI"Dprefixed by `@', that variable shall be inaccessible from Ruby.;T@ o;;[I"=VALUE rb_iv_set(VALUE obj, const char *name, VALUE val) ;T;[o; ;[I"-Sets the value of the instance variable.;T@ S; ; i;I"Control Structure;T@ o;;;;[o;;[I"kVALUE rb_block_call(VALUE recv, ID mid, int argc, VALUE * argv, VALUE (*func) (ANYARGS), VALUE data2) ;T;[o; ;[ I"GCalls a method on the recv, with the method name specified by the ;TI"Dsymbol mid, with argc arguments in argv, supplying func as the ;TI"Hblock. When func is called as the block, it will receive the value ;TI"Ifrom yield as the first argument, and data2 as the second argument. ;TI"AWhen yielded with multiple values (in C, rb_yield_values(), ;TI"Lrb_yield_values2() and rb_yield_splat()), data2 is packed as an Array, ;TI"Lwhereas yielded values can be gotten via argc/argv of the third/fourth ;TI"arguments.;T@ o;;[I"^\[OBSOLETE] VALUE rb_iterate(VALUE (*func1)(), VALUE arg1, VALUE (*func2)(), VALUE arg2) ;T;[ o; ;[I"LCalls the function func1, supplying func2 as the block. func1 will be ;TI"Lcalled with the argument arg1. func2 receives the value from yield as ;TI"5the first argument, arg2 as the second argument.;T@ o; ;[I"OWhen rb_iterate is used in 1.9, func1 has to call some Ruby-level method. ;TI"DThis function is obsolete since 1.9; use rb_block_call instead.;T@ o;;[I"VALUE rb_yield(VALUE val) ;T;[o; ;[I"(Evaluates the block with value val.;T@ o;;[I"_VALUE rb_rescue(VALUE (*func1)(ANYARGS), VALUE arg1, VALUE (*func2)(ANYARGS), VALUE arg2) ;T;[o; ;[ I"KCalls the function func1, with arg1 as the argument. If an exception ;TI"Ioccurs during func1, it calls func2 with arg2 as the first argument ;TI"Hand the exception object as the second argument. The return value ;TI"Kof rb_rescue() is the return value from func1 if no exception occurs, ;TI"from func2 otherwise.;T@ o;;[I"_VALUE rb_ensure(VALUE (*func1)(ANYARGS), VALUE arg1, VALUE (*func2)(ANYARGS), VALUE arg2) ;T;[o; ;[I"JCalls the function func1 with arg1 as the argument, then calls func2 ;TI"?with arg2 if execution terminated. The return value from ;TI"=rb_ensure() is that of func1 when no exception occurred.;T@ o;;[I"DVALUE rb_protect(VALUE (*func) (VALUE), VALUE arg, int *state) ;T;[o; ;[I"HCalls the function func with arg as the argument. If no exception ;TI"Moccurred during func, it returns the result of func and *state is zero. ;TI"IOtherwise, it returns Qnil and sets *state to nonzero. If state is ;TI"(NULL, it is not set in both cases. ;TI"EYou have to clear the error info with rb_set_errinfo(Qnil) when ;TI"#ignoring the caught exception.;T@ o;;[I"!void rb_jump_tag(int state) ;T;[o; ;[I"RContinues the exception caught by rb_protect() and rb_eval_string_protect(). ;TI"Kstate must be the returned value from those functions. This function ;TI" never return to the caller.;T@ o;;[I"void rb_iter_break() ;T;[o; ;[I"LExits from the current innermost block. This function never return to ;TI"the caller.;T@ o;;[I"+void rb_iter_break_value(VALUE value) ;T;[o; ;[I"LExits from the current innermost block with the value. The block will ;TI"Ireturn the given argument value. This function never return to the ;TI"caller.;T@ S; ; i;I"Exceptions and Errors;T@ o;;;;[o;;[I"(void rb_warn(const char *fmt, ...) ;T;[o; ;[I"@Prints a warning message according to a printf-like format.;T@ o;;[I"+void rb_warning(const char *fmt, ...) ;T;[o; ;[I"DPrints a warning message according to a printf-like format, if ;TI"$VERBOSE is true.;T@ o;;[I";void rb_raise(rb_eRuntimeError, const char *fmt, ...) ;T;[o; ;[I"IRaises RuntimeError. The fmt is a format string just like printf().;T@ o;;[I":void rb_raise(VALUE exception, const char *fmt, ...) ;T;[o; ;[I"NRaises a class exception. The fmt is a format string just like printf().;T@ o;;[I")void rb_fatal(const char *fmt, ...) ;T;[o; ;[I"NRaises a fatal error, terminates the interpreter. No exception handling ;TI"Gwill be done for fatal errors, but ensure blocks will be executed.;T@ o;;[I"'void rb_bug(const char *fmt, ...) ;T;[o; ;[I"FTerminates the interpreter immediately. This function should be ;TI"Jcalled under the situation caused by the bug in the interpreter. No ;TI":exception handling nor ensure execution will be done.;T@ o; ;[ I"JNote: In the format string, "%"PRIsVALUE can be used for Object#to_s ;TI"I(or Object#inspect if '+' flag is set) output (and related argument ;TI"Fmust be a VALUE). Since it conflicts with "%i", for integers in ;TI"format strings, use "%d".;T@ S; ; i;I")Initialize and Start the Interpreter;T@ o; ;[I"PThe embedding API functions are below (not needed for extension libraries):;T@ o;;;;[ o;;[I"void ruby_init() ;T;[o; ;[I"!Initializes the interpreter.;T@ o;;[I"/void *ruby_options(int argc, char **argv) ;T;[o; ;[ I"9Process command line arguments for the interpreter. ;TI".And compiles the Ruby source to execute. ;TI"9It returns an opaque pointer to the compiled source ;TI""or an internal special value.;T@ o;;[I" int ruby_run_node(void *n) ;T;[o; ;[I"<Runs the given compiled source and exits this process. ;TI">It returns EXIT_SUCCESS if successfully runs the source. ;TI"'Otherwise, it returns other value.;T@ o;;[I""void ruby_script(char *name) ;T;[o; ;[I"+Specifies the name of the script ($0).;T@ S; ; i;I"%Hooks for the Interpreter Events;T@ o;;;;[o;;[I"[void rb_add_event_hook(rb_event_hook_func_t func, rb_event_flag_t events, VALUE data) ;T;[ o; ;[I"@Adds a hook function for the specified interpreter events. ;TI"%events should be OR'ed value of:;T@ o;;[I"RUBY_EVENT_LINE ;TI"RUBY_EVENT_CLASS ;TI"RUBY_EVENT_END ;TI"RUBY_EVENT_CALL ;TI"RUBY_EVENT_RETURN ;TI"RUBY_EVENT_C_CALL ;TI"RUBY_EVENT_C_RETURN ;TI"RUBY_EVENT_RAISE ;TI"RUBY_EVENT_ALL ;T;0o; ;[I"5The definition of rb_event_hook_func_t is below:;T@ o;;[I"Htypedef void (*rb_event_hook_func_t)(rb_event_t event, VALUE data, ;TI"J VALUE self, ID id, VALUE klass) ;T;0o; ;[I"LThe third argument `data' to rb_add_event_hook() is passed to the hook ;TI"Kfunction as the second argument, which was the pointer to the current ;TI"?NODE in 1.8. See RB_EVENT_HOOKS_HAVE_CALLBACK_DATA below.;T@ o;;[I"9int rb_remove_event_hook(rb_event_hook_func_t func) ;T;[o; ;[I")Removes the specified hook function.;T@ S; ; i;I"Memory usage;T@ o;;;;[o;;[I"2void rb_gc_adjust_memory_usage(ssize_t diff) ;T;[o; ;[I"LAdjusts the amount of registered external memory. You can tell GC how ;TI"Kmuch memory is used by an external library by this function. Calling ;TI"Kthis function with positive diff means the memory usage is increased; ;TI"Gnew memory block is allocated or a block is reallocated as larger ;TI"Lsize. Calling this function with negative diff means the memory usage ;TI"His decreased; a memory block is freed or a block is reallocated as ;TI"5smaller size. This function may trigger the GC.;T@ S; ; i;I"Macros for Compatibility;T@ o; ;[I"GSome macros to check API compatibilities are available by default.;T@ o;;;;[o;;[I"NORETURN_STYLE_NEW ;T;[o; ;[I"EMeans that NORETURN macro is functional style instead of prefix.;T@ o;;[I"HAVE_RB_DEFINE_ALLOC_FUNC ;T;[o; ;[I"LMeans that function rb_define_alloc_func() is provided, that means the ;TI"Ballocation framework is used. This is same as the result of ;TI"1have_func("rb_define_alloc_func", "ruby.h").;T@ o;;[I"HAVE_RB_REG_NEW_STR ;T;[o; ;[I"KMeans that function rb_reg_new_str() is provided, that creates Regexp ;TI"?object from String object. This is same as the result of ;TI"+have_func("rb_reg_new_str", "ruby.h").;T@ o;;[I"HAVE_RB_IO_T ;T;[o; ;[I")Means that type rb_io_t is provided.;T@ o;;[I"USE_SYMBOL_AS_METHOD_NAME ;T;[o; ;[I"@Means that Symbols will be returned as method names, e.g., ;TI"3Module#methods, \#singleton_methods and so on.;T@ o;;[I"HAVE_RUBY_*_H ;T;[o; ;[I"IDefined in ruby.h and means corresponding header is available. For ;TI"Kinstance, when HAVE_RUBY_ST_H is defined you should use ruby/st.h not ;TI"mere st.h.;T@ o;;[I"'RB_EVENT_HOOKS_HAVE_CALLBACK_DATA ;T;[o; ;[I"KMeans that rb_add_event_hook() takes the third argument `data', to be ;TI"-passed to the given event hook function.;T@ S; ; i;I":Appendix C. Functions available for use in extconf.rb;T@ o; ;[I"9See documentation for {mkmf}[rdoc-ref:MakeMakefile].;T@ S; ; i;I" Appendix D. Generational GC;T@ o; ;[I"KRuby 2.1 introduced a generational garbage collector (called RGenGC). ;TI")RGenGC (mostly) keeps compatibility.;T@ o; ;[ I"NGenerally, the use of the technique called write barriers is required in ;TI"-extension libraries for generational GC ;TI"O(http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29). ;TI"ERGenGC works fine without write barriers in extension libraries.;T@ o; ;[I"DIf your library adheres to the following tips, performance can ;TI"Ube further improved. Especially, the "Don't touch pointers directly" section is ;TI"important.;T@ S; ; i;I"Incompatibility;T@ o; ;[I"KYou can't write RBASIC(obj)->klass field directly because it is const ;TI"value now.;T@ o; ;[I"LBasically you should not write this field because MRI expects it to be ;TI"Lan immutable field, but if you want to do it in your extension you can ;TI"!use the following functions:;T@ o;;;;[o;;[I""VALUE rb_obj_hide(VALUE obj) ;T;[o; ;[I"GClear RBasic::klass field. The object will be an internal object. ;TI"5ObjectSpace::each_object can't find this object.;T@ o;;[I"1VALUE rb_obj_reveal(VALUE obj, VALUE klass) ;T;[o; ;[I"&Reset RBasic::klass to be klass. ;TI"<We expect the `klass' is hidden class by rb_obj_hide().;T@ S; ; i;I"Write barriers;T@ o; ;[I"GRGenGC doesn't require write barriers to support generational GC. ;TI"HHowever, caring about write barrier can improve the performance of ;TI"-RGenGC. Please check the following tips.;T@ S; ; i ;I""Don't touch pointers directly;T@ o; ;[I"JIn MRI (include/ruby/ruby.h), some macros to acquire pointers to the ;TI"Binternal data structures are supported such as RARRAY_PTR(), ;TI"RSTRUCT_PTR() and so on.;T@ o; ;[I"NDO NOT USE THESE MACROS and instead use the corresponding C-APIs such as ;TI"-rb_ary_aref(), rb_ary_store() and so on.;T@ S; ; i ;I".Consider whether to insert write barriers;T@ o; ;[I"JYou don't need to care about write barriers if you only use built-in ;TI"types.;T@ o; ;[I"JIf you support T_DATA objects, you may consider using write barriers.;T@ o; ;[ I"FInserting write barriers into T_DATA objects only works with the ;TI"Lfollowing type objects: (a) long-lived objects, (b) when a huge number ;TI"Hof objects are generated and \(c) container-type objects that have ;TI"Lreferences to other objects. If your extension provides such a type of ;TI"7T_DATA objects, consider inserting write barriers.;T@ o; ;[I"C(a): short-lived objects don't become old generation objects. ;TI"C(b): only a few oldgen objects don't have performance impact. ;TI"?\(c): only a few references don't have performance impact.;T@ o; ;[ I"FInserting write barriers is a very difficult hack, it is easy to ;TI"Mintroduce critical bugs. And inserting write barriers has several areas ;TI"Jof overhead. Basically we don't recommend you insert write barriers. ;TI")Please carefully consider the risks.;T@ S; ; i ;I" Combine with built-in types;T@ o; ;[I"KPlease consider utilizing built-in types. Most built-in types support ;TI"Jwrite barrier, so you can use them to avoid manually inserting write ;TI"barriers.;T@ o; ;[ I"KFor example, if your T_DATA has references to other objects, then you ;TI"Ncan move these references to Array. A T_DATA object only has a reference ;TI"Ito an array object. Or you can also use a Struct object to gather a ;TI"GT_DATA object (without any references) and an that Array contains ;TI"references.;T@ o; ;[I"JWith use of such techniques, you don't need to insert write barriers ;TI" anymore.;T@ S; ; i ;I"Insert write barriers;T@ o; ;[ I"K\[AGAIN] Inserting write barriers is a very difficult hack, and it is ;TI"Geasy to introduce critical bugs. And inserting write barriers has ;TI"Nseveral areas of overhead. Basically we don't recommend you insert write ;TI"3barriers. Please carefully consider the risks.;T@ o; ;[I"NBefore inserting write barriers, you need to know about RGenGC algorithm ;TI"M(gc.c will help you). Macros and functions to insert write barriers are ;TI"Iavailable in include/ruby/ruby.h. An example is available in iseq.c.;T@ o; ;[I"IFor a complete guide for RGenGC and write barriers, please refer to ;TI"B<https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/RGenGC>.;T@ S; ; i;I"9Appendix E. RB_GC_GUARD to protect from premature GC;T@ o; ;[I"GC Ruby currently uses conservative garbage collection, thus VALUE ;TI"Kvariables must remain visible on the stack or registers to ensure any ;TI"Nassociated data remains usable. Optimizing C compilers are not designed ;TI"Mwith conservative garbage collection in mind, so they may optimize away ;TI"Nthe original VALUE even if the code depends on data associated with that ;TI"VALUE.;T@ o; ;[I"HThe following example illustrates the use of RB_GC_GUARD to ensure ;TI"Fthe contents of sptr remain valid while the second invocation of ;TI" rb_str_new_cstr is running.;T@ o;;[ I"VALUE s, w; ;TI"const char *sptr; ;TI" ;TI"Ls = rb_str_new_cstr("hello world!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); ;TI"sptr = RSTRING_PTR(s); ;TI"Aw = rb_str_new_cstr(sptr + 6); /* Possible GC invocation */ ;TI" ;TI"ERB_GC_GUARD(s); /* ensure s (and thus sptr) do not get GC-ed */ ;T;0o; ;[ I"NIn the above example, RB_GC_GUARD must be placed _after_ the last use of ;TI"Nsptr. Placing RB_GC_GUARD before dereferencing sptr would be of no use. ;TI"KRB_GC_GUARD is only effective on the VALUE data type, not converted C ;TI"data types.;T@ o; ;[ I"GRB_GC_GUARD would not be necessary at all in the above example if ;TI"Hnon-inlined function calls are made on the `s' VALUE after sptr is ;TI"Gdereferenced. Thus, in the above example, calling any un-inlined ;TI"function on `s' such as:;T@ o;;[I"rb_str_modify(s); ;T;0o; ;[I"AWill ensure `s' stays on the stack or register to prevent a ;TI"/GC invocation from prematurely freeing it.;T@ o; ;[I"GUsing the RB_GC_GUARD macro is preferable to using the "volatile" ;TI"=keyword in C. RB_GC_GUARD has the following advantages:;T@ o;;;;[o;;0;[o; ;[I")the intent of the macro use is clear;T@ o;;0;[o; ;[I"GRB_GC_GUARD only affects its call site, "volatile" generates some ;TI"Fextra code every time the variable is used, hurting optimization.;T@ o;;0;[o; ;[I"B"volatile" implementations may be buggy/inconsistent in some ;TI"Icompilers and architectures. RB_GC_GUARD is customizable for broken ;TI"Bsystems/compilers without negatively affecting other systems.;T: @file@:0@omit_headings_from_table_of_contents_below0
| ver. 1.4 |
Github
|
.
| PHP 8.0.30 | Génération de la page: 0 |
proxy
|
phpinfo
|
Réglages