3 General help and instructions on the subtend layer.
5 1. Exporting Rubinius Data
6 ==========================
8 To export Rubinius data so that it can be used by extensions
9 designed for MRI, you need to convert it into MRI's format.
10 Let us examine, for example, floating point numbers. MRI stores
11 these in a structure called RFloat. This looks like:
17 We can forget about the RBasic structure which makes up the first
18 element in all MRI types. Pretty much all extensions will only
19 care about the rest of the structure. So, in
20 rubinius/shotgun/lib/subtend/ruby.h, we have:
24 typedef struct RFloat RFloat;
26 Now, the actual function to convert from Rubinius data to MRI
27 data is called RFLOAT:
28 RFloat* RFLOAT(VALUE obj);
29 This takes a Rubinius VALUE object and outputs an MRI style
30 R-structure. In ruby.c:
31 RFloat *RFLOAT(VALUE obj) {
35 ret = (RFloat *)AS_HNDL(obj)->data;
38 ret->value = *((double*)BYTES_OF(HNDL(obj)));
39 AS_HNDL(obj)->data = (void*)ret;
44 If we have already done the conversion, we just return the
45 RFloat structure. But we probably have not. So, we allocate
46 some storage. We then set the MRI structure contents (in this
47 case, the double value) based on how the data is stored by
48 Rubinius. Then we store a pointer to the MRI structure as
49 obj->data in case the user repeatedly calls RFLOAT() on the same
50 object and so we can import changed data back into Rubinius.
52 Floating point numbers are very simple. More complex data types
53 may require substantially more effort to convert.
58 After the extension is done mucking about with the R-structure
59 data, we need to copy it back into Rubinius's format. This is
60 so that if the extension changed any data, Rubinius knows about
63 This happens in handle.c. Note that the structures are copied
64 from ruby.h (to prevent including that whole file) and then the
65 magic happens in check_rstruct_data. The RFloat case is as
67 else if (FLOAT_P(o)) {
68 RFloat *rf = (RFloat *)h->data;
69 *((double*)BYTES_OF(o)) = rf->value;
74 Here, we get a handle to the R-struct. We then update the
75 Rubinius data from the MRI R-struct. For a data type more
76 complex than floats, this may be substantially more lines of
77 code. Finally, we free the R-struct pointer.
79 Note that we totally overwrite whatever was previously stored
80 by Rubinius. There's no way to tell whether or not the
81 extension changed the data so the only way to be sure is to