evilr 1.0.0-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/MIT-LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2010-2011 Jeremy Evans
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to
5
+ deal in the Software without restriction, including without limitation the
6
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
+ sell copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16
+ THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
+
data/README.rdoc ADDED
@@ -0,0 +1,148 @@
1
+ = evilr
2
+
3
+ evilr subverts ruby's runtime and lets you do things you shouldn't
4
+ do, such as changing the classes of objects. It's inspired by
5
+ evil.rb, but is a C extension as opposed to ruby code that uses DL.
6
+
7
+ == Why?
8
+
9
+ It's a good way to learn about how ruby works under the hood. It's
10
+ fun to push the boundries of ruby's runtime, to see the difference
11
+ between what's just not allowed (i.e. changing classes) and what's
12
+ not possible for technical reasons (i.e. sharing singleton classes,
13
+ instance variables, or method tables).
14
+
15
+ == Installation
16
+
17
+ gem install evilr
18
+
19
+ == What evil is currently available?
20
+
21
+ * Object
22
+ * class= : Change the class of an object
23
+ * detach_singleton_class : Make current singleton class not a
24
+ singleton, becoming the object's main class.
25
+ * dup_singleton_class : Make a copy of the current singleton
26
+ class as a regular class.
27
+ * evilr_debug_print : Print method ancestry chain to standard
28
+ output.
29
+ * extend_between : Given a module and a block, calls the block
30
+ repeatedly with two arguments, each a module or class in the super
31
+ chain. The first time the block returns true, the module argument
32
+ given to the method is inserted between the given extended modules.
33
+ Starts with the object's singleton class and continues until
34
+ the object's class. If the argument given already extends the
35
+ object, will remove it and reinsert it. If the argument is
36
+ already included in the object's class, raises an exception.
37
+ * pop_singleton_class : Remove closest singleton class from the
38
+ object
39
+ * push_singleton_class : Add a new singleton class to the object
40
+ in front of any existing singleton class.
41
+ * remove_singleton_class : Remove an object's singleton class
42
+ and any modules that extend the object.
43
+ * remove_singleton_classes : Remove all singleton classes
44
+ and extended modules.
45
+ * set_singleton_class : Take a given class and make it the object's
46
+ singleton class, replacing any existing singleton class.
47
+ * swap : Completely swap two objects (singleton class, class,
48
+ instance variables).
49
+ * swap_singleton_class : Swap an object's singleton class with
50
+ another object's singleton class.
51
+ * swap_instance_variables: Swap two instance's instance variables.
52
+ * unextend : Remove a module that extends the object from the super
53
+ chain.
54
+ * unfreeze : Unfreeze the object.
55
+ * Kernel
56
+ * segfault : Dereferences NULL.
57
+ * seppuku : kill -KILL's the current process.
58
+ * set_safe_level : Allows you to lower ruby's $SAFE level.
59
+ * Module
60
+ * include_between : Given a module and a block, calls the block
61
+ repeatedly with two arguments, each a module or class in the super
62
+ chain. The first time the block returns true, the module argument
63
+ given to the method is inserted between the given modules. Continues
64
+ until the end of the super chain. If the argument given is already
65
+ included, will remove it and reinsert it.
66
+ * swap_method_tables : Swap the method tables of the receiver with
67
+ the ones in the given module/class.
68
+ * to_class : Return a copy of the module as a class.
69
+ * uninclude : Remove the given module from the super chain, including
70
+ going into superclasses if the receiver is a class.
71
+ * Class
72
+ * detach_singleton : If the class is a singleton class, remove
73
+ its singleton status.
74
+ * inherit : Allows inheriting from multiple classes, basically
75
+ including them as modules.
76
+ * singleton_class_instance : If the class is a singleton class,
77
+ return the related instance.
78
+ * superclass= : Modify the superclass of the receiver.
79
+ * to_module : Return a copy of the class as a module.
80
+ * UnboundMethod
81
+ * force_bind : Bind the method to the object even if it is a different
82
+ class than the method.
83
+ * Proc
84
+ * self : Get the default receiver of the proc's methods
85
+ * self= : Change the default receiver of the proc's methods
86
+ * Empty
87
+ * A class with no superclass, only allocate, new, initialize, and
88
+ superclass defined. More basic than even BasicObject.
89
+
90
+ == Good bugs
91
+
92
+ If bugs are evil in good code, then surely bugs in evil code are good:
93
+
94
+ http://github.com/jeremyevans/evilr/issues
95
+
96
+ == Contributing
97
+
98
+ I'm happy to accept more evil, hopefully without good bugs and with
99
+ evil specs:
100
+
101
+ http://github.com/jeremyevans/evilr
102
+
103
+ evilr currently requires:
104
+
105
+ * rake
106
+ * rake-compiler
107
+ * rspec
108
+
109
+ == Running the specs
110
+
111
+ Even evil code should have specs! The default rake task runs the
112
+ specs:
113
+
114
+ rake
115
+
116
+ == Platforms Tested
117
+
118
+ === Operating Systems/Platforms
119
+
120
+ * OpenBSD (amd64, i386)
121
+ * Linux (i386)
122
+ * Windows XP (i386)
123
+
124
+ === Compiler Versions
125
+
126
+ * gcc 4.2.1
127
+ * gcc 4.4.5
128
+
129
+ == Ruby Versions
130
+
131
+ * ruby 1.8.6
132
+ * ruby 1.8.7
133
+ * ruby 1.9.2
134
+
135
+ ruby 1.9.1 is not supported. It mostly works but has spec failures.
136
+
137
+ If your platform, compiler version, or ruby version is not listed
138
+ above, please test and send me a report including:
139
+
140
+ * Your operating system and platform (e.g. i386, x86_64/amd64)
141
+ * Your compiler
142
+ * Your ruby version
143
+ * The output of rake
144
+
145
+ == Author
146
+
147
+ Jeremy Evans <code@jeremyevans.net>
148
+
data/Rakefile ADDED
@@ -0,0 +1,41 @@
1
+ require "rake"
2
+ require "rake/clean"
3
+
4
+ CLEAN.include %w'*.core doc ext/evilr/Makefile ext/evilr/evilr.o ext/evilr/evilr.so lib tmp evilr-*.gem'
5
+
6
+ desc "Build the gem"
7
+ task :gem do
8
+ sh %{gem build evilr.gemspec}
9
+ end
10
+
11
+ begin
12
+ require 'rake/extensiontask'
13
+ Rake::ExtensionTask.new('evilr')
14
+ dependencies = [:compile]
15
+ rescue LoadError
16
+ dependencies = []
17
+ end
18
+
19
+ begin
20
+ require "spec/rake/spectask"
21
+
22
+ Spec::Rake::SpecTask.new("spec" => dependencies) do |t|
23
+ t.spec_files = ["spec/evilr_spec.rb"]
24
+ end
25
+ task :default => :spec
26
+
27
+ rescue LoadError
28
+ end
29
+
30
+ desc "Start an IRB shell using the extension"
31
+ task :irb => dependencies do
32
+ require 'irb'
33
+ $:.unshift 'lib'
34
+ require 'evilr'
35
+ c = IRB.conf
36
+ def c.[]=(k,v)
37
+ super unless k == :SCRIPT
38
+ end
39
+ IRB.start
40
+ end
41
+
data/ext/evilr/evilr.c ADDED
@@ -0,0 +1,993 @@
1
+ #include <signal.h>
2
+ #include <string.h>
3
+ #include <stdio.h>
4
+ #include <sys/types.h>
5
+ #include <unistd.h>
6
+
7
+ #include <ruby.h>
8
+ #ifdef RUBY19
9
+ #include <ruby/st.h>
10
+ #else
11
+ #include <st.h>
12
+ #endif
13
+
14
+ /* ruby uses a magic number for this, arguably the only time
15
+ * it is more evil that evilr. */
16
+ #ifndef SAFE_LEVEL_MAX
17
+ #define SAFE_LEVEL_MAX 4
18
+ #endif
19
+
20
+ /* Partial struct definition == evil */
21
+ struct METHOD {
22
+ VALUE recv;
23
+ VALUE rclass;
24
+ ID id;
25
+ };
26
+
27
+ #ifdef RUBY19
28
+ struct BLOCK {
29
+ VALUE self;
30
+ VALUE *lfp;
31
+ VALUE *dfp;
32
+ void *block_iseq;
33
+ VALUE proc;
34
+ };
35
+ #else
36
+ /* More partial definition evil */
37
+ struct BLOCK {
38
+ void *var;
39
+ void *body;
40
+ VALUE self;
41
+ };
42
+ #endif
43
+
44
+ /* Ruby 1.8.6 support */
45
+ #ifndef RCLASS_SUPER
46
+ #define RCLASS_SUPER(c) RCLASS(c)->super
47
+ #endif
48
+ #ifndef RCLASS_IV_TBL
49
+ #define RCLASS_IV_TBL(c) RCLASS(c)->iv_tbl
50
+ #endif
51
+ #ifndef RCLASS_M_TBL
52
+ #define RCLASS_M_TBL(c) RCLASS(c)->m_tbl
53
+ #endif
54
+
55
+ #define OBJECT_SIZE sizeof(struct RClass)
56
+ #define RBASIC_SET_KLASS(o, c) (RBASIC(o)->klass = c)
57
+ #define RBASIC_KLASS(o) (RBASIC(o)->klass)
58
+ #define RBASIC_FLAGS(o) (RBASIC(o)->flags)
59
+ #define IS_SINGLETON_CLASS(o) (FL_TEST(o, FL_SINGLETON))
60
+ #define HAS_SINGLETON_CLASS(o) (FL_TEST(RBASIC_KLASS(o), FL_SINGLETON))
61
+
62
+ #ifdef RUBY19
63
+ #define RCLASS_SET_SUPER(o, c) (RCLASS(o)->ptr->super = c)
64
+ #else
65
+ #define RCLASS_SET_SUPER(o, c) (RCLASS(o)->super = c)
66
+ #define ROBJECT_IVPTR(o) (ROBJECT(o)->iv_tbl)
67
+ extern int ruby_safe_level;
68
+ #endif
69
+
70
+ VALUE empty;
71
+ ID evilr__attached;
72
+ ID evilr__bind;
73
+ ID evilr__clone;
74
+
75
+ /* Helper functions */
76
+
77
+ /* Raise TypeError if an immediate value is given. */
78
+ static void evilr__check_immediate(VALUE self) {
79
+ if (SPECIAL_CONST_P(self)) {
80
+ rb_raise(rb_eTypeError, "can't use immediate value");
81
+ }
82
+ }
83
+
84
+ /* Raise TypeError if either self or other is an immediate value. */
85
+ static void evilr__check_immediates(VALUE self, VALUE other) {
86
+ evilr__check_immediate(self);
87
+ evilr__check_immediate(other);
88
+ }
89
+
90
+ /* Raise TypeError if self doesn't have the given ruby internal type
91
+ * number (e.g. T_OBJECT). */
92
+ static void evilr__check_type(unsigned int type, VALUE self) {
93
+ if (BUILTIN_TYPE(self) != type) {
94
+ rb_raise(rb_eTypeError, "incompatible type used");
95
+ }
96
+ }
97
+
98
+ /* Return the ruby internal type number that instances of the
99
+ * given class use. */
100
+ static unsigned int evilr__class_type(VALUE klass) {
101
+ evilr__check_type(T_CLASS, klass);
102
+ return BUILTIN_TYPE(rb_obj_alloc(klass));
103
+ }
104
+
105
+ /* Raise TypeError if instances of the given class don't have the
106
+ * given ruby internal type number. */
107
+ static void evilr__check_class_type(unsigned int type, VALUE self) {
108
+ if (evilr__class_type(self) != type) {
109
+ rb_raise(rb_eTypeError, "incompatible type used");
110
+ }
111
+ }
112
+
113
+ /* Raise TypeError if the given value has the ruby internal type number T_DATA. */
114
+ static void evilr__check_data_type(VALUE self) {
115
+ if (BUILTIN_TYPE(self) == T_DATA) {
116
+ rb_raise(rb_eTypeError, "incompatible type used");
117
+ }
118
+ }
119
+
120
+ /* Return the next class in the super chain, skipping any iclasses (included modules).
121
+ * Returns NULL if this is the last class in the super chain. */
122
+ static VALUE evilr__next_class(VALUE klass) {
123
+ VALUE c;
124
+ for (c = RCLASS_SUPER(klass); c && BUILTIN_TYPE(c) != T_CLASS; c = RCLASS_SUPER(c)); /* empty */
125
+ return c;
126
+ }
127
+
128
+ /* If the given class includes no modules, return it. Otherwise, return the last iclass
129
+ * before the next class in the super chain. */
130
+ static VALUE evilr__iclass_before_next_class(VALUE klass) {
131
+ VALUE c, i = NULL;
132
+ for (c = RCLASS_SUPER(klass); c && BUILTIN_TYPE(c) != T_CLASS; i = c, c = RCLASS_SUPER(c)); /* empty */
133
+ return i == NULL ? klass : i;
134
+ }
135
+
136
+ /* Walk the super chain from klass until either before or an iclass for mod is encountered. If
137
+ * before is encountered first, return NULL. If an iclass for mod is encountered first, return
138
+ * the iclass. */
139
+ static VALUE evilr__iclass_matching_before(VALUE klass, VALUE mod, VALUE before) {
140
+ VALUE c;
141
+ for (c = RCLASS_SUPER(klass); c && c != before; c = RCLASS_SUPER(c)) {
142
+ if (BUILTIN_TYPE(c) == T_ICLASS && RBASIC_KLASS(c) == mod) {
143
+ return c;
144
+ }
145
+ }
146
+ return NULL;
147
+ }
148
+
149
+ /* If there is an iclass for mod anywhere in the super chain of klass, return the iclass.
150
+ * Otherwise, return NULL. */
151
+ static VALUE evilr__iclass_matching(VALUE klass, VALUE mod) {
152
+ return evilr__iclass_matching_before(klass, mod, NULL);
153
+ }
154
+
155
+ /* If self has a singleton class, set the superclass of the
156
+ * singleton class to the given klass, keeping all modules
157
+ * that are included in the singleton class. Otherwise, set the
158
+ * object's klass to the given klass. */
159
+ void evilr__reparent_singleton_class(VALUE self, VALUE klass) {
160
+ VALUE self_klass = RBASIC_KLASS(self);
161
+
162
+ if (IS_SINGLETON_CLASS(self_klass)) {
163
+ RCLASS_SET_SUPER(evilr__iclass_before_next_class(self_klass), klass);
164
+ rb_clear_cache_by_class(self_klass);
165
+ } else {
166
+ RBASIC_SET_KLASS(self, klass);
167
+ }
168
+ }
169
+
170
+ /* Set the superclass of self to the given klass, keeping all
171
+ * modules that are included in the class. */
172
+ void evilr__reparent_class(VALUE self, VALUE klass) {
173
+ RCLASS_SET_SUPER(evilr__iclass_before_next_class(self), klass);
174
+ rb_clear_cache_by_class(self);
175
+ }
176
+
177
+ /* Raise TypeError if self is an immediate value or if klass is
178
+ * not a Class. */
179
+ void evilr__check_obj_and_class(VALUE self, VALUE klass) {
180
+ evilr__check_immediates(self, klass);
181
+ evilr__check_type(T_CLASS, klass);
182
+ }
183
+
184
+ /* If no arguments are given, return Object. If an argument is
185
+ * given and it is a class object whose instances use the ruby
186
+ * internal class number T_OBJECT, return that class. If an argument
187
+ * is given and it isn't a class or it's instances don't use T_OBJECT,
188
+ * return a TypeError. Otherwise, return an ArgumentError. */
189
+ static VALUE evilr__optional_class(int argc, VALUE *argv) {
190
+ VALUE klass;
191
+
192
+ switch(argc) {
193
+ case 0:
194
+ klass = rb_cObject;
195
+ break;
196
+ case 1:
197
+ klass = argv[0];
198
+ evilr__check_class_type(T_OBJECT, klass);
199
+ break;
200
+ default:
201
+ rb_raise(rb_eArgError, "wrong number of arguments: %i for 1", argc);
202
+ break;
203
+ }
204
+ return klass;
205
+ }
206
+
207
+ /* Make the given klass the singleton class of self. */
208
+ void evilr__make_singleton(VALUE self, VALUE klass) {
209
+ FL_SET(klass, FL_SINGLETON);
210
+ RBASIC_SET_KLASS(self, klass);
211
+ rb_singleton_class_attached(klass, self);
212
+ }
213
+
214
+ /* Check that super is a Class object whose instances use the same internal
215
+ * type number as instances of klass, and that the instances don't use
216
+ * type number T_DATA. */
217
+ void evilr__check_compatible_classes(VALUE klass, VALUE super) {
218
+ evilr__check_immediate(super);
219
+ evilr__check_type(T_CLASS, super);
220
+ evilr__check_class_type(evilr__class_type(klass), super);
221
+ evilr__check_data_type(rb_obj_alloc(klass));
222
+ }
223
+
224
+ /* Walk the super chain starting with the given iclass and include
225
+ * the modules related to each iclass into the mod such that the
226
+ * order of the initial iclass super chain and mod's super chain are
227
+ * the same. */
228
+ void evilr__include_iclasses(VALUE mod, VALUE iclass) {
229
+ if (iclass && BUILTIN_TYPE(iclass) == T_ICLASS) {
230
+ evilr__include_iclasses(mod, RCLASS_SUPER(iclass));
231
+ rb_include_module(mod, RBASIC_KLASS(iclass));
232
+ }
233
+ rb_clear_cache_by_class(mod);
234
+ }
235
+
236
+ /* Ruby methods */
237
+
238
+ /* call-seq:
239
+ * class=(klass) -> Object
240
+ *
241
+ * Modifies the receiver's class to be +klass+. The receiver's current class
242
+ * and any singleton class (and any modules that extend the object) are
243
+ * ignored. If the receiver is an immediate or instances of +klass+ don't use the
244
+ * same internal type as the receiver, a +TypeError+ is raised.
245
+ */
246
+ static VALUE evilr_class_e(VALUE self, VALUE klass) {
247
+ evilr__check_immediate(self);
248
+ evilr__check_type(evilr__class_type(klass), self);
249
+ evilr__check_data_type(self);
250
+
251
+ RBASIC_SET_KLASS(self, klass);
252
+ return self;
253
+ }
254
+
255
+ /* call-seq:
256
+ * evilr_debug_print -> nil
257
+ *
258
+ * Prints to stdout the receiver and all entries in the receiver's klass's super chain,
259
+ * using the pointers of the current entry, it's klass, iv_tbl, m_tbl, and super entry,
260
+ * as well as the entry's flags. If Class or Module is given, uses their
261
+ * super chain, not the super chain of their klass. If the receiver is an immediate value,
262
+ * a +TypeError+ is raised. */
263
+ static VALUE evilr_debug_print(VALUE self) {
264
+ if (self == NULL) {
265
+ return Qnil;
266
+ }
267
+ evilr__check_immediate(self);
268
+ switch(BUILTIN_TYPE(self)) {
269
+ case T_CLASS:
270
+ case T_ICLASS:
271
+ case T_MODULE:
272
+ printf("self %p klass %p flags 0x%lx iv_tbl %p m_tbl %p super %p\n", (void *)self, (void *)RBASIC_KLASS(self), RBASIC_FLAGS(self), (void *)RCLASS_IV_TBL(self), (void *)RCLASS_M_TBL(self), (void *)RCLASS_SUPER(self));
273
+ self = RCLASS_SUPER(self);
274
+ break;
275
+ default:
276
+ printf("self %p klass %p flags 0x%lx iv_tbl/ptr %p\n", (void *)self, (void *)RBASIC_KLASS(self), RBASIC_FLAGS(self), (void *)ROBJECT_IVPTR(self));
277
+ self = RBASIC_KLASS(self);
278
+ break;
279
+ }
280
+ return evilr_debug_print(self);
281
+ }
282
+
283
+
284
+ /* call-seq:
285
+ * swap(other) -> self
286
+ *
287
+ * Swap the contents of the receiver with +other+:
288
+ *
289
+ * a = []
290
+ * b = {}
291
+ * a.swap(b) # => {}
292
+ * a # => {}
293
+ * b # => []
294
+ *
295
+ * You cannot swap a Class or Module except with another
296
+ * Class or Module, and you can only swap a Class with a Class and
297
+ * a Module with a Module (no swapping a Class with Module), and you
298
+ * cannot swap immediate values. If an invalid swap attempt is
299
+ * detected, a +TypeError+ is raised.*/
300
+ static VALUE evilr_swap(VALUE self, VALUE other) {
301
+ char tmp[OBJECT_SIZE];
302
+ evilr__check_immediates(self, other);
303
+ if ((BUILTIN_TYPE(self) == T_MODULE || BUILTIN_TYPE(self) == T_CLASS ||
304
+ BUILTIN_TYPE(other) == T_MODULE || BUILTIN_TYPE(other) == T_CLASS) &&
305
+ BUILTIN_TYPE(self) != BUILTIN_TYPE(other)) {
306
+ rb_raise(rb_eTypeError, "incompatible types used");
307
+ }
308
+ memcpy(tmp, ROBJECT(self), OBJECT_SIZE);
309
+ memcpy(ROBJECT(self), ROBJECT(other), OBJECT_SIZE);
310
+ memcpy(ROBJECT(other), tmp, OBJECT_SIZE);
311
+ return self;
312
+ }
313
+
314
+ /* call-seq:
315
+ * swap_instance_variables(other) -> self
316
+ *
317
+ * Swaps only the instance variables of the receiver and +other+.
318
+ * You can only swap the instance variables between two objects that
319
+ * use the internal type number T_OBJECT, or between Classes and Modules.
320
+ * You cannot swap instance variables of immediate values, since they
321
+ * do not have instance variables. Invalid swap attempts will raise
322
+ * +TypeError+. */
323
+ static VALUE evilr_swap_instance_variables(VALUE self, VALUE other) {
324
+ #ifndef RUBY19
325
+ struct st_table *tmp;
326
+ #endif
327
+ evilr__check_immediates(self, other);
328
+
329
+ switch(BUILTIN_TYPE(self)) {
330
+ case T_OBJECT:
331
+ if (BUILTIN_TYPE(other) != T_OBJECT) {
332
+ goto bad_types;
333
+ }
334
+ break;
335
+ case T_MODULE:
336
+ case T_CLASS:
337
+ if (BUILTIN_TYPE(other) != T_MODULE && BUILTIN_TYPE(other) != T_CLASS) {
338
+ goto bad_types;
339
+ }
340
+ break;
341
+ default:
342
+ bad_types:
343
+ rb_raise(rb_eTypeError, "incompatible types used");
344
+ }
345
+
346
+ #ifdef RUBY19
347
+ if (BUILTIN_TYPE(self) == T_MODULE || BUILTIN_TYPE(self) == T_CLASS) {
348
+ struct st_table *tmp;
349
+ tmp = RCLASS_IV_TBL(self);
350
+ RCLASS(self)->ptr->iv_tbl = RCLASS_IV_TBL(other);
351
+ RCLASS(other)->ptr->iv_tbl = tmp;
352
+ } else {
353
+ char tmp[OBJECT_SIZE];
354
+ memcpy(tmp, &(ROBJECT(self)->as), sizeof(ROBJECT(tmp)->as));
355
+ memcpy(&(ROBJECT(self)->as), &(ROBJECT(other)->as), sizeof(ROBJECT(self)->as));
356
+ memcpy(&(ROBJECT(other)->as), tmp, sizeof(ROBJECT(other)->as));
357
+ }
358
+ #else
359
+ /* RClass and RObject have iv_tbl at same position in the structure
360
+ * so no funny business is needed */
361
+ tmp = ROBJECT_IVPTR(self);
362
+ ROBJECT(self)->iv_tbl = ROBJECT_IVPTR(other);
363
+ ROBJECT(other)->iv_tbl = tmp;
364
+ #endif
365
+ return self;
366
+ }
367
+
368
+ /* call-seq:
369
+ * swap_method_tables(other) -> self
370
+ *
371
+ * Swap the method table of the receiver with the method table of the given
372
+ * class or module. If +other+ is not a class or module, raise a +TypeError+. */
373
+ static VALUE evilr_swap_method_tables(VALUE self, VALUE other) {
374
+ struct st_table *tmp;
375
+
376
+ evilr__check_immediate(other);
377
+ if(BUILTIN_TYPE(other) != T_MODULE && BUILTIN_TYPE(other) != T_CLASS) {
378
+ rb_raise(rb_eTypeError, "non-class or module used");
379
+ }
380
+
381
+ tmp = RCLASS_M_TBL(self);
382
+ RCLASS(self)->m_tbl = RCLASS_M_TBL(other);
383
+ RCLASS(other)->m_tbl = tmp;
384
+ rb_clear_cache_by_class(self);
385
+ rb_clear_cache_by_class(other);
386
+ return self;
387
+ }
388
+
389
+ /* call-seq:
390
+ * swap_singleton_class(other) -> self
391
+ *
392
+ * Swap the singleton classes of the receiver and +other+. If either
393
+ * the receiver or +other+ is an immediate, a +TypeError+ is raised.
394
+ * If either object does not have a singleton class, an empty singleton
395
+ * class is created for it before swapping. Any modules that extend
396
+ * either object are swapped as well.
397
+ * */
398
+ static VALUE evilr_swap_singleton_class(VALUE self, VALUE other) {
399
+ VALUE tmp;
400
+
401
+ evilr__check_immediates(self, other);
402
+
403
+ /* Create singleton classes to be swapped if they doesn't exist */
404
+ (void)rb_singleton_class(other);
405
+ (void)rb_singleton_class(self);
406
+
407
+ tmp = rb_obj_class(other);
408
+ evilr__reparent_singleton_class(other, rb_obj_class(self));
409
+ evilr__reparent_singleton_class(self, tmp);
410
+
411
+ tmp = RBASIC_KLASS(self);
412
+ RBASIC_SET_KLASS(self, RBASIC_KLASS(other));
413
+ RBASIC_SET_KLASS(other, tmp);
414
+
415
+ /* Attach each singleton class to its object */
416
+ rb_singleton_class_attached(RBASIC_KLASS(self), self);
417
+ rb_singleton_class_attached(RBASIC_KLASS(other), other);
418
+
419
+ return self;
420
+ }
421
+
422
+ /* call-seq:
423
+ * unfreeze -> self
424
+ *
425
+ * Unfreezes the given object. Will raise a +SecurityError+ if
426
+ * <tt>$SAFE</tt> > 0. Has no effect if the object is not yet frozen. */
427
+ static VALUE evilr_unfreeze(VALUE self) {
428
+ if (rb_safe_level() > 0) {
429
+ rb_raise(rb_eSecurityError, "can't unfreeze objects when $SAFE > 0");
430
+ }
431
+ FL_UNSET(self, FL_FREEZE);
432
+ return self;
433
+ }
434
+
435
+ /* call-seq:
436
+ * set_safe_level=(int) -> int
437
+ *
438
+ * Sets the <tt>$SAFE</tt> level to the given integer. If the number is
439
+ * greater than 4, sets it to 4. Allows lowering the <tt>$SAFE</tt> level
440
+ * by passing an integer lower than the current level. Returns the value
441
+ * passed in. */
442
+ static VALUE evilr_set_safe_level(VALUE self, VALUE safe) {
443
+ int s = NUM2INT(safe);
444
+ if (s > SAFE_LEVEL_MAX) {
445
+ s = SAFE_LEVEL_MAX;
446
+ }
447
+ #ifdef RUBY19
448
+ rb_set_safe_level_force(s);
449
+ #else
450
+ ruby_safe_level = s;
451
+ #endif
452
+ return safe;
453
+ }
454
+
455
+ /* call-seq:
456
+ * uninclude(mod) -> mod || nil
457
+ *
458
+ * Unincludes the given module +mod+ from the receiver or any of the receiver's
459
+ * ancestors. Walks the super chain of the receiver, and if an iclass for +mod+ is
460
+ * encountered, the super chain is modified to skip that iclass. Returns +mod+ if
461
+ * an iclass for mod was present in the super chain, and +nil+ otherwise. If +mod+ is
462
+ * not a Module, a +TypeError+ is raised. */
463
+ static VALUE evilr_uninclude(VALUE klass, VALUE mod) {
464
+ VALUE cur, prev;
465
+
466
+ evilr__check_immediate(mod);
467
+ evilr__check_type(T_MODULE, mod);
468
+
469
+ for (prev = klass, cur = RCLASS_SUPER(klass); cur ; prev = cur, cur = RCLASS_SUPER(cur)) {
470
+ if (BUILTIN_TYPE(prev) == T_CLASS) {
471
+ rb_clear_cache_by_class(prev);
472
+ }
473
+ if (BUILTIN_TYPE(cur) == T_ICLASS && RBASIC_KLASS(cur) == mod) {
474
+ RCLASS_SET_SUPER(prev, RCLASS_SUPER(cur));
475
+ return mod;
476
+ }
477
+ }
478
+
479
+ return Qnil;
480
+ }
481
+
482
+ /* call-seq:
483
+ * unextend(mod) -> mod || nil
484
+ *
485
+ * Unextends the given module +mod+ from the receiver. If the receiver's class includes the
486
+ * module, does not uninclude it, so this should not affect any other objects besides the
487
+ * receiver. If +mod+ already extended the object, returns +mod+, otherwise returns +nil+.
488
+ * Raises +TypeError+ if +mod+ is not a Module or if the receiver is an immediate. */
489
+ static VALUE evilr_unextend(VALUE self, VALUE mod) {
490
+ VALUE prev, cur;
491
+
492
+ evilr__check_immediates(self, mod);
493
+ evilr__check_type(T_MODULE, mod);
494
+
495
+ self = rb_singleton_class(self);
496
+ rb_clear_cache_by_class(self);
497
+ for (prev = self, cur = RCLASS_SUPER(self); cur && BUILTIN_TYPE(cur) != T_CLASS; prev = cur, cur = RCLASS_SUPER(cur)) {
498
+ if (BUILTIN_TYPE(cur) == T_ICLASS && RBASIC_KLASS(cur) == mod) {
499
+ RCLASS_SET_SUPER(prev, RCLASS_SUPER(cur));
500
+ return mod;
501
+ }
502
+ }
503
+
504
+ return Qnil;
505
+ }
506
+
507
+ #define INCLUDE_BETWEEN_VAL(x) (x) ? (BUILTIN_TYPE(x) == T_ICLASS ? RBASIC_KLASS(x) : (x)) : Qnil
508
+ /* call-seq:
509
+ * include_between(mod){|p, c| } -> mod || nil
510
+ *
511
+ * Walks the receiver's super chain, yielding the previous and current entries in
512
+ * the super chain at every step. The first time the block returns +true+, +mod+ is
513
+ * inserted into the super chain between the two values, and the method returns
514
+ * immediately. Raises +TypeError+ if +mod+ is not a Module.
515
+ * If the block ever returns +true+, the return value is +mod+. If
516
+ * the block never returns +true+, the return value is +nil+. On the first block call,
517
+ * the first block argument is the receiver, and on the last block call, the last block
518
+ * argument is +nil+. */
519
+ static VALUE evilr_include_between(VALUE klass, VALUE mod) {
520
+ VALUE iclass, prev, cur;
521
+
522
+ evilr__check_immediate(mod);
523
+ evilr__check_type(T_MODULE, mod);
524
+
525
+ /* Create ICLASS for module by inserting it and removing it.
526
+ * If module already in super chain, will change it's position. */
527
+ rb_include_module(klass, mod);
528
+ iclass = evilr__iclass_matching(klass, mod);
529
+ evilr_uninclude(klass, mod);
530
+
531
+ for (prev = klass, cur = RCLASS_SUPER(klass); prev ; prev = cur, cur = cur ? RCLASS_SUPER(cur) : cur) {
532
+ if (BUILTIN_TYPE(prev) == T_CLASS) {
533
+ rb_clear_cache_by_class(prev);
534
+ }
535
+ if (rb_yield_values(2, INCLUDE_BETWEEN_VAL(prev), INCLUDE_BETWEEN_VAL(cur)) == Qtrue) {
536
+ RCLASS_SET_SUPER(prev, iclass);
537
+ RCLASS_SET_SUPER(iclass, cur);
538
+ return mod;
539
+ }
540
+ }
541
+ return Qnil;
542
+ }
543
+
544
+ /* call-seq:
545
+ * extend_between(mod){|p, c| } -> mod || nil
546
+ *
547
+ * Walks the receiver's singleton class's super chain until it reaches the receiver's
548
+ * class, yielding the previous and current entries in the super chain at every step.
549
+ * The first time the block returns +true+, +mod+ is inserted into the super chain
550
+ * between the two values and the method returns immediately. Raises +TypeError+ if
551
+ * +mod+ is not a Module or if the receiver is an immediate.
552
+ * If the block ever returns +true+, the return value is
553
+ * +mod+. If the block never returns +true+, the return value is +nil+. On the first block call,
554
+ * the first block argument is the receiver's singleton class, and on the last block call,
555
+ * the last block argument is the receiver's class. */
556
+ static VALUE evilr_extend_between(VALUE self, VALUE mod) {
557
+ VALUE sc, iclass, klass, prev, cur;
558
+
559
+ evilr__check_immediates(self, mod);
560
+ evilr__check_type(T_MODULE, mod);
561
+
562
+ sc = rb_singleton_class(self);
563
+ klass = rb_obj_class(self);
564
+ rb_extend_object(self, mod);
565
+ iclass = evilr__iclass_matching_before(sc, mod, klass);
566
+ if (iclass == NULL) {
567
+ rb_raise(rb_eArgError, "module already included in object's class");
568
+ }
569
+ evilr_unextend(self, mod);
570
+
571
+ for (prev = sc, cur = RCLASS_SUPER(sc); prev && prev != klass; prev = cur, cur = cur ? RCLASS_SUPER(cur) : cur) {
572
+ if (rb_yield_values(2, INCLUDE_BETWEEN_VAL(prev), INCLUDE_BETWEEN_VAL(cur)) == Qtrue) {
573
+ RCLASS_SET_SUPER(prev, iclass);
574
+ RCLASS_SET_SUPER(iclass, cur);
575
+ return mod;
576
+ }
577
+ }
578
+ return Qnil;
579
+ }
580
+
581
+ /* call-seq:
582
+ * detach_singleton -> self
583
+ *
584
+ * If the receiver is a singleton class, it is transformed into a
585
+ * regular class and it is detached from the instance. Note that
586
+ * this means it becomes the class of the object to which it was previous
587
+ * attached. If the receiver is not a singleton class, has no effect.
588
+ * Returns the receiver. */
589
+ static VALUE evilr_detach_singleton(VALUE klass) {
590
+ if (IS_SINGLETON_CLASS(klass)) {
591
+ FL_UNSET(klass, FL_SINGLETON);
592
+ if (RCLASS_IV_TBL(klass)) {
593
+ st_delete(RCLASS_IV_TBL(klass), (st_data_t*)&evilr__attached, 0);
594
+ }
595
+ }
596
+ return klass;
597
+ }
598
+
599
+ /* call-seq:
600
+ * detach_singleton_class -> Class
601
+ *
602
+ * If the receiver has a singleton class, it is detached from the
603
+ * receiver and becomes the receiver's class. If the receiver is
604
+ * an immediate, a +TypeError+ is raised. Returns the (possibly new) class
605
+ * of the receiver. */
606
+ static VALUE evilr_detach_singleton_class(VALUE self) {
607
+ evilr__check_immediate(self);
608
+ return evilr_detach_singleton(RBASIC_KLASS(self));
609
+ }
610
+
611
+ /* call-seq:
612
+ * dup_singleton_class(klass=Object) -> Class || nil
613
+ *
614
+ * If the receiver has a singleton class, a copy of the class is returned,
615
+ * and the superclass of that class is set to the given +klass+. Any
616
+ * modules that extend the object become modules included in the returned class.
617
+ * If the receiver does not have a singleton class, +nil+ is returned and no
618
+ * changes are made. If the receiver is an immediate, a +TypeError+ is raised. */
619
+ static VALUE evilr_dup_singleton_class(int argc, VALUE *argv, VALUE self) {
620
+ VALUE klass;
621
+ evilr__check_immediate(self);
622
+
623
+ if (!HAS_SINGLETON_CLASS(self)) {
624
+ return Qnil;
625
+ }
626
+ klass = evilr__optional_class(argc, argv);
627
+ self = rb_singleton_class_clone(self);
628
+ evilr__reparent_class(self, klass);
629
+ FL_UNSET(self, FL_SINGLETON);
630
+ return self;
631
+ }
632
+
633
+ /* call-seq:
634
+ * push_singleton_class(klass) -> klass
635
+ *
636
+ * Makes the given class the closest singleton class of the receiver, without changing any
637
+ * existing singleton class relationships. Designed to be used with +pop_singleton_class+
638
+ * to implement a method table stack on an object. If the receiver is an immediate or
639
+ * +klass+ is not a class, raises +TypeError+. */
640
+ static VALUE evilr_push_singleton_class(VALUE self, VALUE klass) {
641
+ evilr__check_obj_and_class(self, klass);
642
+ evilr__reparent_class(evilr__iclass_before_next_class(klass), RBASIC_KLASS(self));
643
+ evilr__make_singleton(self, klass);
644
+ return klass;
645
+ }
646
+
647
+ /* call-seq:
648
+ * pop_singleton_class -> Class || nil
649
+ *
650
+ * Removes the closest singleton class from the receiver and returns it.
651
+ * If the receiver does not have a singleton class, does nothing and returns +nil+.
652
+ * Designed to be used with +push_singleton_class+
653
+ * to implement a method table stack on an object. If the receiver is an immediate,
654
+ * raises +TypeError+. */
655
+ static VALUE evilr_pop_singleton_class(VALUE self) {
656
+ VALUE klass;
657
+
658
+ evilr__check_immediate(self);
659
+ klass = RBASIC_KLASS(self);
660
+
661
+ if (IS_SINGLETON_CLASS(klass)) {
662
+ RBASIC_SET_KLASS(self, evilr__next_class(klass));
663
+ } else {
664
+ klass = Qnil;
665
+ }
666
+ return klass;
667
+ }
668
+
669
+ /* call-seq:
670
+ * remove_singleton_classes -> nil
671
+ *
672
+ * Removes all singleton classes from the receiver. Designed to be used with
673
+ * +push_singleton_class+ and +pop_singleton_class+ to implement a method table
674
+ * stack on an object, this clears the stack. If the receiver is an immediate,
675
+ * raises +TypeError+. */
676
+ static VALUE evilr_remove_singleton_classes(VALUE self) {
677
+ evilr__check_immediate(self);
678
+ RBASIC_SET_KLASS(self, rb_obj_class(self));
679
+ return Qnil;
680
+ }
681
+
682
+ /* call-seq:
683
+ * set_singleton_class(klass) -> klass
684
+ *
685
+ * Makes the given +klass+ the singleton class of the receiver,
686
+ * ignoring any existing singleton class and modules extending the receiver.
687
+ * Modules already included in +klass+ become modules that extend the receiver.
688
+ * If the receiver is an immediate or +klass+ is not a Class,
689
+ * raises +TypeError+. */
690
+ static VALUE evilr_set_singleton_class(VALUE self, VALUE klass) {
691
+ evilr__check_obj_and_class(self, klass);
692
+ RCLASS_SET_SUPER(evilr__iclass_before_next_class(klass), rb_obj_class(self));
693
+ rb_clear_cache_by_class(klass);
694
+ evilr__make_singleton(self, klass);
695
+ return klass;
696
+ }
697
+
698
+ /* call-seq:
699
+ * remove_singleton_class -> klass || nil
700
+ *
701
+ * Removes the singleton class of the receiver, detaching it from the
702
+ * receiver and making it a regular class. If the receiver does not
703
+ * currently have a singleton class, returns +nil+. If the receiver is an
704
+ * immediate, raises +TypeError+. */
705
+ static VALUE evilr_remove_singleton_class(VALUE self) {
706
+ VALUE klass;
707
+ evilr__check_immediate(self);
708
+
709
+ if (HAS_SINGLETON_CLASS(self)) {
710
+ klass = evilr_detach_singleton_class(self);
711
+ RBASIC_SET_KLASS(self, evilr__next_class(klass));
712
+ } else {
713
+ klass = Qnil;
714
+ }
715
+ return klass;
716
+ }
717
+
718
+ /* call-seq:
719
+ * singleton_class_instance -> Object || nil
720
+ *
721
+ * Returns the object attached to the singleton class.
722
+ * If the class does not have an object attached to it (possibly because
723
+ * it isn't a singleton class), returns +nil+. */
724
+ static VALUE evilr_singleton_class_instance(VALUE klass) {
725
+ VALUE obj;
726
+ if(RCLASS_IV_TBL(klass) && st_lookup(RCLASS_IV_TBL(klass), evilr__attached, &obj)) {
727
+ return obj;
728
+ }
729
+ return Qnil;
730
+ }
731
+
732
+ /* call-seq:
733
+ * to_module -> Module
734
+ *
735
+ * Makes a copy of the class, converts the copy to a module, and returns it. The
736
+ * returned module can be included in other classes. */
737
+ static VALUE evilr_to_module(VALUE klass) {
738
+ VALUE mod, iclass;
739
+
740
+ if (IS_SINGLETON_CLASS(klass)) {
741
+ if((mod = evilr_singleton_class_instance(klass))) {
742
+ mod = rb_singleton_class_clone(mod);
743
+ (void)evilr_detach_singleton(mod);
744
+ } else {
745
+ rb_raise(rb_eTypeError, "singleton class without attached instance");
746
+ }
747
+ } else {
748
+ mod = rb_obj_clone(klass);
749
+ }
750
+
751
+ RBASIC_SET_KLASS(mod, rb_cModule);
752
+ iclass = RCLASS_SUPER(mod);
753
+ RCLASS_SET_SUPER(mod, NULL);
754
+ FL_UNSET(mod, T_MASK);
755
+ FL_SET(mod, T_MODULE);
756
+ evilr__include_iclasses(mod, iclass);
757
+
758
+ return mod;
759
+ }
760
+
761
+ /* call-seq:
762
+ * to_class(klass=Object) -> Class
763
+ *
764
+ * Makes a copy of the module, converts the copy to a class, and returns it. The
765
+ * returned class can then have instances created from it. The +klass+ argument
766
+ * sets the superclass of the returned class. If +klass+ is not a Class,
767
+ * raises +TypeError+. */
768
+ static VALUE evilr_to_class(int argc, VALUE *argv, VALUE self) {
769
+ VALUE klass = evilr__optional_class(argc, argv);
770
+
771
+ self = rb_obj_clone(self);
772
+ RBASIC_SET_KLASS(self, rb_singleton_class(klass));
773
+ RCLASS_SET_SUPER(self, klass);
774
+ FL_UNSET(self, T_MASK);
775
+ FL_SET(self, T_CLASS);
776
+ return self;
777
+ }
778
+
779
+ /* call-seq:
780
+ * flags -> Integer
781
+ *
782
+ * Returns the internal flags value of the receiver as an +Integer+. Raises +TypeError+
783
+ * if the receiver is an immediate. */
784
+ static VALUE evilr_flags(VALUE self) {
785
+ evilr__check_immediate(self);
786
+ return UINT2NUM(RBASIC_FLAGS(self));
787
+ }
788
+
789
+ /* call-seq:
790
+ * superclass=(klass) -> klass
791
+ *
792
+ * Modifies the superclass of the current class to be the given
793
+ * class. Any modules included in the receiver remain included.
794
+ * Raises +TypeError+ if klass is not a Class or if the receiver
795
+ * and class are not compatible (where their instances use
796
+ * different internal types). */
797
+ static VALUE evilr_superclass_e(VALUE klass, VALUE super) {
798
+ VALUE iclass;
799
+ evilr__check_compatible_classes(klass, super);
800
+ iclass = evilr__iclass_before_next_class(klass);
801
+ RCLASS_SET_SUPER(iclass, super);
802
+ rb_clear_cache_by_class(klass);
803
+ return super;
804
+ }
805
+
806
+ /* call-seq:
807
+ * inherit(*classes) -> self
808
+ *
809
+ * Make copies of all given +classes+ as modules, and includes
810
+ * those modules in the receiver. Raises +TypeError+ if any of the
811
+ * +classes+ is not a Class or is not compatible with the receiver. */
812
+ static VALUE evilr_inherit(int argc, VALUE* argv, VALUE klass) {
813
+ int i;
814
+
815
+ for(i = 0; i < argc; i++) {
816
+ evilr__check_compatible_classes(klass, argv[i]);
817
+ rb_include_module(klass, evilr_to_module(argv[i]));
818
+ }
819
+
820
+ return klass;
821
+ }
822
+
823
+ /* call-seq:
824
+ * force_bind(object) -> Method
825
+ *
826
+ * Returns a +Method+ object bound to the given object. Doesn't
827
+ * check that the method is compatible with the object, unlike +bind+. */
828
+ static VALUE evilr_force_bind(VALUE self, VALUE obj) {
829
+ struct METHOD *data;
830
+
831
+ evilr__check_immediate(obj);
832
+ self = rb_funcall(self, evilr__clone, 0);
833
+ /* Data_Get_Struct seems to complain about types on 1.9,
834
+ * so skip the type check. */
835
+ data = (struct METHOD*)DATA_PTR(self);
836
+ data->rclass = CLASS_OF(obj);
837
+ return rb_funcall(self, evilr__bind, 1, obj);
838
+ }
839
+
840
+ /* call-seq:
841
+ * self -> Object
842
+ *
843
+ * Returns the self of the receiver, which is the default context
844
+ * used in evaluating the receiver. */
845
+ static VALUE evilr_self(VALUE self) {
846
+ struct BLOCK *data;
847
+ data = (struct BLOCK*)DATA_PTR(self);
848
+ return data->self;
849
+ }
850
+
851
+ /* call-seq:
852
+ * self=(object) -> object
853
+ *
854
+ * Sets the self of the receiver to the given object, modifying the
855
+ * used in evaluating the receiver. Example:
856
+ *
857
+ * p = Proc.new{self[:a]}
858
+ * h1 = {:a=>1}
859
+ * h2 = {:a=>2}
860
+ * p.self = h1
861
+ * p.call # => 1
862
+ * p.self = h2
863
+ * p.call # => 2
864
+ * */
865
+ static VALUE evilr_self_e(VALUE self, VALUE obj) {
866
+ struct BLOCK *data;
867
+ data = (struct BLOCK*)DATA_PTR(self);
868
+ data->self = obj;
869
+ return data->self;
870
+ }
871
+
872
+ /* call-seq:
873
+ * segfault
874
+ *
875
+ * Dereferences the NULL pointer, which should cause SIGSEGV
876
+ * (a segmentation fault), and the death of the process, though
877
+ * it could possibly be rescued. */
878
+ static VALUE evilr_segfault(VALUE self) {
879
+ self = *(char *)NULL;
880
+ return self;
881
+ }
882
+
883
+ /* call-seq:
884
+ * seppuku
885
+ *
886
+ * Kills the current process with SIGKILL, which should
887
+ * terminate the process immediately without any recovery possible. */
888
+ static VALUE evilr_seppuku(VALUE self) {
889
+ kill(getpid(), SIGKILL);
890
+ return self;
891
+ }
892
+
893
+ /* call-seq:
894
+ * allocate -> object
895
+ *
896
+ * Allocate memory for the new instance. Basically a copy of
897
+ * +rb_class_allocate_instance+. */
898
+ static VALUE evilr_empty_alloc(VALUE klass) {
899
+ NEWOBJ(obj, struct RObject);
900
+ OBJSETUP(obj, klass, T_OBJECT);
901
+ return (VALUE)obj;
902
+ }
903
+
904
+ /* call-seq:
905
+ * new(*args)-> object
906
+ *
907
+ * Allocates memory for the instance and then calls initialize
908
+ * on the object. */
909
+ static VALUE evilr_empty_new(int argc, VALUE* argv, VALUE klass) {
910
+ VALUE obj;
911
+ obj = evilr_empty_alloc(klass);
912
+ rb_obj_call_init(obj, argc, argv);
913
+ return obj;
914
+ }
915
+
916
+ /* call-seq:
917
+ * superclass -> Class || nil
918
+ *
919
+ * Returns the superclass of the class, or nil if current class is
920
+ * +Empty+. Basically a copy of the standard superclass method,
921
+ * without some checking. */
922
+ static VALUE evilr_empty_superclass(VALUE klass) {
923
+ return klass == empty ? Qnil : evilr__next_class(klass);
924
+ }
925
+
926
+ /* call-seq:
927
+ * initialize -> self
928
+ *
929
+ * Returns the receiver. */
930
+ static VALUE evilr_empty_initialize(VALUE self) {
931
+ return self;
932
+ }
933
+
934
+ /* Empty is an almost completely empty class, even more basic than
935
+ * BasicObject. It has no parent class, and only implements
936
+ * +allocate+, +new+, +initialize+, and +superclass+. All other
937
+ * behavior must be added by the user. Note that if you want to
938
+ * call a method defined in Object, Kernel, or BasicObject that
939
+ * isn't defined in Empty, you can use <tt>UndefinedMethod#force_bind</tt>,
940
+ * to do so:
941
+ *
942
+ * Object.instance_method(:puts).force_bind(Empty.new).call()
943
+ */
944
+ void Init_evilr(void) {
945
+ empty = rb_define_class("Empty", rb_cObject);
946
+ rb_define_alloc_func(empty, evilr_empty_alloc);
947
+ rb_define_singleton_method(empty, "new", evilr_empty_new, -1);
948
+ rb_define_singleton_method(empty, "superclass", evilr_empty_superclass, 0);
949
+ rb_define_method(empty, "initialize", evilr_empty_initialize, 0);
950
+ RCLASS_SET_SUPER(empty, NULL);
951
+ rb_global_variable(&empty);
952
+
953
+ evilr__attached = rb_intern("__attached__");
954
+ evilr__bind = rb_intern("bind");
955
+ evilr__clone = rb_intern("clone");
956
+
957
+ rb_define_method(rb_cObject, "class=", evilr_class_e, 1);
958
+ rb_define_method(rb_cObject, "evilr_debug_print", evilr_debug_print, 0);
959
+ rb_define_method(rb_cObject, "extend_between", evilr_extend_between, 1);
960
+ rb_define_method(rb_cObject, "flags", evilr_flags, 0);
961
+ rb_define_method(rb_cObject, "detach_singleton_class", evilr_detach_singleton_class, 0);
962
+ rb_define_method(rb_cObject, "dup_singleton_class", evilr_dup_singleton_class, -1);
963
+ rb_define_method(rb_cObject, "pop_singleton_class", evilr_pop_singleton_class, 0);
964
+ rb_define_method(rb_cObject, "push_singleton_class", evilr_push_singleton_class, 1);
965
+ rb_define_method(rb_cObject, "remove_singleton_class", evilr_remove_singleton_class, 0);
966
+ rb_define_method(rb_cObject, "remove_singleton_classes", evilr_remove_singleton_classes, 0);
967
+ rb_define_method(rb_cObject, "set_singleton_class", evilr_set_singleton_class, 1);
968
+ rb_define_method(rb_cObject, "swap", evilr_swap, 1);
969
+ rb_define_method(rb_cObject, "swap_instance_variables", evilr_swap_instance_variables, 1);
970
+ rb_define_method(rb_cObject, "swap_singleton_class", evilr_swap_singleton_class, 1);
971
+ rb_define_method(rb_cObject, "unextend", evilr_unextend, 1);
972
+ rb_define_method(rb_cObject, "unfreeze", evilr_unfreeze, 0);
973
+
974
+ rb_define_method(rb_mKernel, "segfault", evilr_segfault, 0);
975
+ rb_define_method(rb_mKernel, "seppuku", evilr_seppuku, 0);
976
+ rb_define_method(rb_mKernel, "set_safe_level", evilr_set_safe_level, 1);
977
+
978
+ rb_define_method(rb_cModule, "include_between", evilr_include_between, 1);
979
+ rb_define_method(rb_cModule, "swap_method_tables", evilr_swap_method_tables, 1);
980
+ rb_define_method(rb_cModule, "to_class", evilr_to_class, -1);
981
+ rb_define_method(rb_cModule, "uninclude", evilr_uninclude, 1);
982
+
983
+ rb_define_method(rb_cClass, "detach_singleton", evilr_detach_singleton, 0);
984
+ rb_define_method(rb_cClass, "inherit", evilr_inherit, -1);
985
+ rb_define_method(rb_cClass, "singleton_class_instance", evilr_singleton_class_instance, 0);
986
+ rb_define_method(rb_cClass, "superclass=", evilr_superclass_e, 1);
987
+ rb_define_method(rb_cClass, "to_module", evilr_to_module, 0);
988
+
989
+ rb_define_method(rb_cUnboundMethod, "force_bind", evilr_force_bind, 1);
990
+
991
+ rb_define_method(rb_cProc, "self", evilr_self, 0);
992
+ rb_define_method(rb_cProc, "self=", evilr_self_e, 1);
993
+ }