public
Description: Rubinius, the Ruby VM
Homepage: http://rubini.us
Clone URL: git://github.com/evanphx/rubinius.git
Tons of stuff (too much probably)
Evan Phoenix (author)
Wed May 07 18:05:09 -0700 2008
commit  feb91b43f113f8dc3b5e28c569cabc0a9c3d508c
tree    8fc9bbf14c77c67c4d0726c48eb93c3a27ed69a5
parent  611cd7440cacf3fa3c730f5093dc66e3f8e33d2e
...
4
5
6
7
 
8
9
10
11
12
13
 
 
 
 
 
14
15
16
...
23
24
25
 
 
 
 
 
 
 
26
27
28
...
4
5
6
 
7
8
9
 
 
 
 
10
11
12
13
14
15
16
17
...
24
25
26
27
28
29
30
31
32
33
34
35
36
0
@@ -4,13 +4,14 @@
0
 namespace rubinius {
0
   class Array : public BuiltinType {
0
     public:
0
-    const static size_t fields = 4;
0
+    const static size_t fields = 5;
0
     const static object_type type = ArrayType;
0
 
0
-    INTEGER total;
0
-    Tuple* tuple;
0
-    INTEGER start;
0
-    OBJECT shared;
0
+    OBJECT __ivars__; // slot
0
+    INTEGER total; // slot
0
+    Tuple* tuple; // slot
0
+    INTEGER start; // slot
0
+    OBJECT shared; // slot
0
 
0
     size_t size() {
0
       return total->n2i();
0
@@ -23,6 +24,13 @@ namespace rubinius {
0
     OBJECT set(STATE, size_t idx, OBJECT val);
0
     OBJECT append(STATE, OBJECT val);
0
     bool   includes_p(STATE, OBJECT val);
0
+
0
+    class Info : public TypeInfo {
0
+    public:
0
+      Info(object_type type) : TypeInfo(type) { }
0
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
0
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
0
+    };
0
   };
0
 };
0
 
...
170
171
172
173
 
174
175
176
...
253
254
255
256
257
258
259
...
297
298
299
300
 
 
301
302
303
...
170
171
172
 
173
174
175
176
...
253
254
255
 
256
257
258
...
296
297
298
 
299
300
301
302
303
0
@@ -170,7 +170,7 @@ namespace rubinius {
0
   }
0
 
0
   void Bignum::init(STATE) {
0
-    state->add_type_info(new Bignum::Info(G(bignum)));
0
+    state->add_type_info(new Bignum::Info(Bignum::type));
0
   }
0
 
0
   Bignum* Bignum::create(STATE, native_int num) {
0
@@ -253,7 +253,6 @@ namespace rubinius {
0
 
0
   INTEGER Bignum::div(STATE, INTEGER b, INTEGER mod_obj) {
0
     NMP;
0
-    mp_int *mod = MP(mod_obj);
0
     mp_int m, x, y, z;
0
 
0
     if(kind_of<Fixnum>(b)) {
0
@@ -297,7 +296,8 @@ namespace rubinius {
0
       mp_copy(&y, &m);
0
     }
0
 
0
-    if(mod) {
0
+    if(!mod_obj->nil_p()) {
0
+      mp_int *mod = MP(mod_obj);
0
       mp_copy(&m, mod);
0
     }
0
 
...
57
58
59
60
 
61
62
63
...
57
58
59
 
60
61
62
63
0
@@ -57,7 +57,7 @@ namespace rubinius {
0
 
0
     class Info : public TypeInfo {
0
     public:
0
-      Info(Class* cls) : TypeInfo(cls) { }
0
+      Info(object_type type) : TypeInfo(type) { }
0
       virtual void cleanup(OBJECT obj);
0
     };
0
   };
...
9
10
11
 
 
 
 
 
 
 
12
13
14
...
33
34
35
36
 
37
38
39
40
41
42
...
9
10
11
12
13
14
15
16
17
18
19
20
21
...
40
41
42
 
43
44
45
 
 
 
46
0
@@ -9,6 +9,13 @@ namespace rubinius {
0
   }
0
 
0
   void Channel::send(STATE, OBJECT val) {
0
+    if(!waiting->empty_p()) {
0
+      Thread* thr = as<Thread>(waiting->shift(state));
0
+      thr->set_top(state, val);
0
+      state->queue_thread(thr);
0
+      return;
0
+    }
0
+
0
     if(value->nil_p()) {
0
       List* lst = List::create(state);
0
       lst->append(state, val);
0
@@ -33,10 +40,7 @@ namespace rubinius {
0
   }
0
 
0
   bool Channel::has_readers_p() {
0
-    return false;
0
+    return !waiting->empty_p();
0
   }
0
 
0
-  void Thread::sleep_for(STATE, Channel* chan) {
0
-
0
-  }
0
 }
...
7
8
9
10
11
 
 
 
12
13
14
15
16
 
 
 
 
 
 
 
17
18
19
 
20
21
22
...
7
8
9
 
 
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
0
@@ -7,16 +7,25 @@ namespace rubinius {
0
     const static size_t fields = 3;
0
     const static object_type type = ChannelType;
0
 
0
-    OBJECT value;
0
-    List* waiting;
0
+    OBJECT __ivars__; // slot
0
+    OBJECT value; // slot
0
+    List* waiting; // slot
0
 
0
     static Channel* create(STATE);
0
     void send(STATE, OBJECT);
0
     void receive(STATE);
0
     bool has_readers_p();
0
+
0
+    class Info : public TypeInfo {
0
+    public:
0
+      Info(object_type type) : TypeInfo(type) { }
0
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
0
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
0
+    };
0
   };
0
 
0
   class ChannelCallback : public ObjectCallback {
0
+  public:
0
     TypedRoot<Channel*> channel;
0
 
0
     ChannelCallback(STATE, Channel* chan) : ObjectCallback(state) {
...
78
79
80
81
82
 
83
84
85
86
87
88
 
89
90
91
...
78
79
80
 
 
81
82
83
84
85
86
 
87
88
89
90
0
@@ -78,14 +78,13 @@ namespace rubinius {
0
   MetaClass* MetaClass::attach(STATE, OBJECT obj, OBJECT sup) {
0
     MetaClass *meta;
0
 
0
-    meta = (MetaClass*)state->om->new_object(G(metaclass),
0
-                                             MetaClass::fields);
0
+    meta = (MetaClass*)state->new_object(G(metaclass));
0
     if(!sup) { sup = obj->klass; }
0
     meta->IsMeta = TRUE;
0
     SET(meta, attached_instance, obj);
0
     meta->setup(state);
0
     SET(meta, superclass, sup);
0
-    state->om->set_class(obj, meta);
0
+    SET(obj, klass, meta);
0
 
0
     return meta;
0
   }
...
6
7
8
9
 
10
11
12
13
14
15
16
17
18
 
 
 
 
 
19
20
21
...
28
29
30
 
 
 
 
 
 
 
31
32
33
34
35
 
36
37
38
39
40
41
 
 
 
 
42
43
44
45
46
47
 
 
 
 
 
 
 
48
49
50
...
57
58
59
60
 
61
62
63
64
65
66
67
 
68
69
 
 
 
 
 
 
 
70
71
72
73
 
 
74
75
 
 
 
 
 
 
 
 
76
77
78
...
6
7
8
 
9
10
11
 
 
 
 
 
 
 
12
13
14
15
16
17
18
19
...
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 
40
41
42
 
 
 
 
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
...
69
70
71
 
72
73
74
 
 
 
 
 
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
 
92
93
94
95
96
97
98
99
100
101
102
0
@@ -6,16 +6,14 @@
0
 namespace rubinius {
0
   class Module : public BuiltinType {
0
     public:
0
-    const static size_t fields = 7;
0
+    const static size_t fields = 5;
0
     const static object_type type = ModuleType;
0
 
0
-    OBJECT instance_variables;
0
-    LookupTable* method_table;
0
-    OBJECT method_cache;
0
-    SYMBOL name;
0
-    LookupTable* constants;
0
-    OBJECT encloser;
0
-    Class* superclass;
0
+    OBJECT __ivars__; // slot
0
+    LookupTable* method_table; // slot
0
+    SYMBOL name; // slot
0
+    LookupTable* constants; // slot
0
+    Module* superclass; // slot
0
 
0
     static Module* create(STATE);
0
     void setup(STATE);
0
@@ -28,23 +26,37 @@ namespace rubinius {
0
     OBJECT get_const(STATE, char* sym);
0
 
0
     void set_name(STATE, Module* under, SYMBOL name);
0
+
0
+    class Info : public TypeInfo {
0
+    public:
0
+      Info(object_type type) : TypeInfo(type) { }
0
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
0
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
0
+    };
0
   };
0
 
0
   class Class : public Module {
0
     public:
0
-    const static size_t fields = 11;
0
+    const static size_t fields = 9;
0
     const static object_type type = ClassType;
0
 
0
-    FIXNUM instance_fields;
0
-    OBJECT has_ivars;
0
-    OBJECT needs_cleanup;
0
-    FIXNUM instance_type;
0
+    FIXNUM instance_fields; // slot
0
+    OBJECT has_ivars; // slot
0
+    OBJECT needs_cleanup; // slot
0
+    FIXNUM instance_type; // slot
0
 
0
     void set_object_type(size_t type) {
0
       instance_type = Object::i2n(type);
0
     }
0
 
0
     static Class* create(STATE, Class* super);
0
+
0
+    class Info : public TypeInfo {
0
+    public:
0
+      Info(object_type type) : TypeInfo(type) { }
0
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
0
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
0
+    };
0
   };
0
 
0
   /* See t1 */
0
@@ -57,22 +69,34 @@ namespace rubinius {
0
 
0
   class MetaClass : public Class {
0
     public:
0
-    const static size_t fields = 12;
0
+    const static size_t fields = 10;
0
     const static object_type type = MetaclassType;
0
 
0
-    OBJECT attached_instance;
0
-
0
-    static bool is_a(OBJECT obj) {
0
-      return obj->obj_type == MetaclassType;
0
-    }
0
+    OBJECT attached_instance; // slot
0
 
0
     static MetaClass* attach(STATE, OBJECT obj, OBJECT sup = NULL);
0
+
0
+    class Info : public TypeInfo {
0
+    public:
0
+      Info(object_type type) : TypeInfo(type) { }
0
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
0
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
0
+    };
0
   };
0
 
0
   class IncludedModule : public Module {
0
     public:
0
+    const static size_t field = 6;
0
+    const static object_type type = IncModType;
0
 
0
-    OBJECT module;
0
+    OBJECT module; // slot
0
+
0
+    class Info : public TypeInfo {
0
+    public:
0
+      Info(object_type type) : TypeInfo(type) { }
0
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
0
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
0
+    };
0
   };
0
 
0
 };
...
1
2
 
3
4
5
...
7
8
9
10
11
 
 
12
13
14
...
1
2
3
4
5
6
...
8
9
10
 
 
11
12
13
14
15
0
@@ -1,5 +1,6 @@
0
 #include "builtin.hpp"
0
 #include "ffi.hpp"
0
+#include "marshal.hpp"
0
 
0
 namespace rubinius {
0
   CompiledMethod* CompiledMethod::create(STATE) {
0
@@ -7,8 +8,8 @@ namespace rubinius {
0
     return cm;
0
   }
0
 
0
-  CompiledMethod::Visibility* CompiledMethod::Visibility::create(STATE) {
0
-    return (CompiledMethod::Visibility*)state->new_object(G(cmethod_vis));
0
+  MethodVisibility* MethodVisibility::create(STATE) {
0
+    return (MethodVisibility*)state->new_object(G(cmethod_vis));
0
   }
0
 
0
   void CompiledMethod::post_marshal(STATE) {
...
13
14
15
 
 
 
16
17
18
...
21
22
23
 
 
 
 
24
25
26
27
28
29
30
 
31
32
33
...
37
38
39
40
 
41
42
 
43
44
45
...
13
14
15
16
17
18
19
20
21
...
24
25
26
27
28
29
30
31
32
33
34
35
36
 
37
38
39
40
...
44
45
46
 
47
48
 
49
50
51
52
0
@@ -13,6 +13,9 @@ namespace rubinius {
0
 
0
   }
0
 
0
+  void MethodContext::Info::mark(MethodContext* obj) {
0
+  }
0
+
0
   BlockContext* BlockContext::create(STATE) {
0
     return (BlockContext*)state->new_struct(G(blokctx), sizeof(BlockContext));
0
   }
0
@@ -21,13 +24,17 @@ namespace rubinius {
0
 
0
   }
0
 
0
+  void BlockEnvironment::call(STATE, Message& msg) {
0
+
0
+  }
0
+
0
   BlockContext* BlockEnvironment::create_context(STATE) {
0
     BlockContext* ctx = BlockContext::create(state);
0
     SET(ctx, sender, (MethodContext*)Qnil);
0
     SET(ctx, name, (SYMBOL)this);
0
     SET(ctx, cm, method);
0
     SET(ctx, stack, Tuple::create(state, method->stack_size->to_nint()));
0
-    
0
+
0
     ctx->vmm = method->vmmethod(state);
0
     ctx->ip = 0;
0
     ctx->sp = method->number_of_locals() - 1;
0
@@ -37,9 +44,9 @@ namespace rubinius {
0
 
0
   BlockEnvironment* BlockEnvironment::under_context(STATE, CompiledMethod* cm,
0
       MethodContext* parent, MethodContext* active) {
0
-    
0
+
0
     BlockEnvironment* be = (BlockEnvironment*)state->new_object(G(blokenv));
0
-    
0
+
0
     parent->reference(state);
0
     active->reference(state);
0
 
...
27
28
29
30
 
31
32
33
...
37
38
39
 
 
40
41
42
...
52
53
54
55
 
 
 
 
56
57
 
 
 
 
 
 
58
59
60
...
27
28
29
 
30
31
32
33
...
37
38
39
40
41
42
43
44
...
54
55
56
 
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
0
@@ -27,7 +27,7 @@ namespace rubinius {
0
     int    sp;
0
     size_t args;
0
     OBJECT block;
0
-    SYMBOL name;
0
+    OBJECT name;
0
     bool   no_value;
0
 
0
     /* Locals are stored at the top of the stack. */
0
@@ -37,6 +37,8 @@ namespace rubinius {
0
     void reference(STATE);
0
 
0
     class Info : public TypeInfo {
0
+    public:
0
+      Info(object_type type) : TypeInfo(type) { }
0
       virtual void mark(MethodContext* obj);
0
     };
0
   };
0
@@ -52,9 +54,18 @@ namespace rubinius {
0
 
0
     static BlockContext* create(STATE);
0
 
0
-    class Info : public MethodContext::Info { };
0
+    class Info : public MethodContext::Info {
0
+    public:
0
+      Info(object_type type) : MethodContext::Info(type) { }
0
+    };
0
   };
0
 
0
+  template <>
0
+    static bool kind_of<MethodContext>(OBJECT obj) {
0
+      return obj->obj_type == MethodContext::type ||
0
+        obj->obj_type == BlockContext::type;
0
+    }
0
+
0
 }
0
 
0
 #endif
...
11
12
13
 
 
 
 
 
 
 
 
 
 
 
14
15
16
...
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
0
@@ -11,6 +11,17 @@ namespace rubinius {
0
     return flt;
0
   }
0
 
0
+  OBJECT Float::compare(STATE, Float* other) {
0
+    double b = other->to_double();
0
+    if(val < b) {
0
+      return Object::i2n(-1);
0
+    } else if(val > b) {
0
+      return Object::i2n(1);
0
+    } else {
0
+      return Object::i2n(0);
0
+    }
0
+  }
0
+
0
   Float* Float::coerce(STATE, OBJECT value) {
0
     if(value->fixnum_p()) {
0
       return Float::create(state, (double)(as<Fixnum>(value)->to_nint()));
...
17
18
19
20
 
21
22
23
24
25
 
26
 
27
28
29
...
36
37
38
 
 
 
 
 
39
40
41
...
17
18
19
 
20
21
22
23
24
25
26
27
28
29
30
31
...
38
39
40
41
42
43
44
45
46
47
48
0
@@ -17,13 +17,15 @@ namespace rubinius {
0
     static bool is_a(OBJECT obj) {
0
       return obj->obj_type == FloatType;
0
     }
0
-    
0
+
0
     double val;
0
 
0
     static Float* create(STATE, double val);
0
     static Float* coerce(STATE, OBJECT value);
0
     double to_double(STATE) { return val; }
0
+    double to_double() { return val; }
0
     void into_string(STATE, char* buf, size_t sz);
0
+    OBJECT compare(STATE, Float* other);
0
 
0
     static int radix()      { return FLT_RADIX; }
0
     static int rounds()     { return FLT_ROUNDS; }
0
@@ -36,6 +38,11 @@ namespace rubinius {
0
     static int dig()        { return DBL_DIG; }
0
     static int mant_dig()   { return DBL_MANT_DIG; }
0
     static double epsilon() { return DBL_EPSILON; }
0
+
0
+    class Info : public TypeInfo {
0
+    public:
0
+      Info(object_type type) : TypeInfo(type) { }
0
+    };
0
   };
0
 }
0
 
...
1
2
3
4
5
6
7
8
...
26
27
28
29
30
 
 
31
32
33
...
42
43
44
45
46
 
 
47
48
 
49
50
51
 
 
52
53
54
 
 
55
56
57
 
 
58
59
60
61
62
63
64
 
65
66
67
...
70
71
72
73
 
74
75
76
 
 
77
78
 
79
80
 
81
82
83
...
85
86
87
88
89
90
 
91
92
93
94
95
96
97
 
98
 
 
99
100
101
...
112
113
114
115
 
116
117
118
 
 
119
120
121
122
123
124
125
126
127
 
128
 
 
129
130
131
...
136
137
138
139
 
 
 
140
141
142
 
 
143
144
 
145
146
147
148
149
 
 
150
151
 
152
153
154
155
 
156
157
 
158
159
160
...
171
172
173
174
175
 
 
176
177
178
...
183
184
185
186
 
187
188
189
190
191
192
193
194
195
 
 
196
197
198
 
 
 
 
 
199
 
 
 
200
201
202
...
207
208
209
210
 
211
212
213
214
215
216
217
218
219
 
 
220
221
222
 
 
 
 
 
223
 
 
 
224
225
226
...
232
233
234
235
236
 
 
237
238
239
...
241
242
243
244
245
 
 
246
247
248
...
251
252
253
254
255
 
 
256
257
258
259
260
261
 
262
263
264
...
268
269
270
271
272
273
274
 
 
275
276
277
...
313
314
315
316
 
317
318
319
...
1
2
 
3
 
4
5
6
...
24
25
26
 
 
27
28
29
30
31
...
40
41
42
 
 
43
44
45
 
46
47
 
 
48
49
50
 
 
51
52
53
 
 
54
55
56
57
58
59
60
61
 
62
63
64
65
...
68
69
70
 
71
72
 
 
73
74
75
 
76
77
 
78
79
80
81
...
83
84
85
 
 
 
86
87
88
 
 
 
 
 
89
90
91
92
93
94
95
...
106
107
108
 
109
110
 
 
111
112
113
114
115
116
 
 
 
 
 
117
118
119
120
121
122
123
...
128
129
130
 
131
132
133
134
135
 
136
137
138
 
139
140
141
142
143
 
144
145
146
 
147
148
149
150
 
151
152
 
153
154
155
156
...
167
168
169
 
 
170
171
172
173
174
...
179
180
181
 
182
183
 
 
 
 
 
 
 
 
184
185
186
 
 
187
188
189
190
191
192
193
194
195
196
197
198
...
203
204
205
 
206
207
 
 
 
 
 
 
 
 
208
209
210
 
 
211
212
213
214
215
216
217
218
219
220
221
222
...
228
229
230
 
 
231
232
233
234
235
...
237
238
239
 
 
240
241
242
243
244
...
247
248
249
 
 
250
251
252
253
254
255
256
 
257
258
259
260
...
264
265
266
 
 
 
 
267
268
269
270
271
...
307
308
309
 
310
311
312
313
0
@@ -1,8 +1,6 @@
0
 #include "builtin.hpp"
0
 
0
-#define MAX_DENSITY 0.75
0
 #define find_bin(hash, total) (hash & (total - 1))
0
-#define hash_redistribute_p(hash) (hash->entries->n2i() >= MAX_DENSITY * hash->bins->n2i())
0
 
0
 #define CSM_SIZE 12
0
 namespace rubinius {
0
@@ -26,8 +24,8 @@ namespace rubinius {
0
   Hash* Hash::dup(STATE) {
0
     size_t size, i;
0
     Hash *dup;
0
-    OBJECT tmp, ent, next;
0
-    Tuple *vals, *lst;
0
+    OBJECT tmp;
0
+    Tuple *vals, *lst, *ent, *next;
0
 
0
     size = bins->n2i();
0
     dup = Hash::create(state, size);
0
@@ -42,26 +40,26 @@ namespace rubinius {
0
     SET(dup, values, vals);
0
 
0
     for(i = 0; i < size; i++) {
0
-      tmp = (Tuple*)values->at(i);
0
-      if(tmp->nil_p()) continue;
0
+      tmp = try_as<Tuple>(values->at(i));
0
+      if(!tmp) continue;
0
 
0
-      ent = tmp->dup(state);
0
+      ent = as<Tuple>(tmp->dup(state));
0
       vals->put(state, i, ent);
0
-      next = ent->at(3);
0
-      lst = (Tuple*)ent;
0
+      next = try_as<Tuple>(ent->at(3));
0
+      lst = ent;
0
 
0
-      while(!next->nil_p()) {
0
-        next = next->dup(state);
0
+      while(next) {
0
+        next = as<Tuple>(next->dup(state));
0
         lst->put(state, 3, next);
0
-        lst = (Tuple*)next;
0
-        next = next->at(3);
0
+        lst = next;
0
+        next = try_as<Tuple>(next->at(3));
0
       }
0
     }
0
 
0
     return dup;
0
   }
0
 
0
-  OBJECT Hash::entry_new(STATE, hashval hsh, OBJECT key, OBJECT data) {
0
+  Tuple* Hash::entry_new(STATE, hashval hsh, OBJECT key, OBJECT data) {
0
     Tuple* tup = Tuple::create(state, 4);
0
     tup->put(state, 0, Object::i2n(hsh));
0
     tup->put(state, 1, key);
0
@@ -70,14 +68,14 @@ namespace rubinius {
0
     return tup;
0
   }
0
 
0
-  OBJECT Hash::entry_append(STATE, OBJECT top, OBJECT nxt) {
0
+  Tuple* Hash::entry_append(STATE, Tuple* top, Tuple* nxt) {
0
     int depth = 1;
0
-    Tuple* cur = (Tuple*)top->at(3);
0
-    Tuple* last = (Tuple*)top;
0
+    Tuple* cur = try_as<Tuple>(top->at(3));
0
+    Tuple* last = top;
0
 
0
-    while(!cur->nil_p()) {
0
+    while(cur) {
0
       last = cur;
0
-      cur = (Tuple*)cur->at(3);
0
+      cur = try_as<Tuple>(cur->at(3));
0
       depth++;
0
     }
0
 
0
@@ -85,17 +83,13 @@ namespace rubinius {
0
     return nxt;
0
   }
0
 
0
-  OBJECT Hash::add_entry(STATE, hashval hsh, OBJECT ent) {
0
-    OBJECT entry;
0
-
0
+  OBJECT Hash::add_entry(STATE, hashval hsh, Tuple* ent) {
0
     size_t bin = find_bin(hsh, bins->n2i());
0
 
0
-    entry = values->at(bin);
0
-
0
-    if(entry->nil_p()) {
0
-      values->put(state, bin, ent);
0
-    } else {
0
+    if(Tuple* entry = try_as<Tuple>(values->at(bin))) {
0
       entry_append(state, entry, ent);
0
+    } else {
0
+      values->put(state, bin, ent);
0
     }
0
 
0
     entries = Object::i2n(entries->n2i() + 1);
0
@@ -112,20 +106,18 @@ namespace rubinius {
0
     Tuple* new_values = Tuple::create(state, size);
0
 
0
     for(size_t i = 0; i < num; i++) {
0
-      Tuple* entry = (Tuple*)values->at(i);
0
+      Tuple* entry = try_as<Tuple>(values->at(i));
0
 
0
-      while(!entry->nil_p()) {
0
-        Tuple* next = (Tuple*)entry->at(3);
0
+      while(entry) {
0
+        Tuple* next = try_as<Tuple>(entry->at(3));
0
         entry->put(state, 3, Qnil);
0
 
0
         native_int hash = as<Integer>(entry->at(0))->n2i();
0
         size_t bin = find_bin(hash, size);
0
-        OBJECT slot = new_values->at(bin);
0
-
0
-        if(slot->nil_p()) {
0
-          new_values->put(state, bin, entry);
0
-        } else {
0
+        if(Tuple* slot = try_as<Tuple>(new_values->at(bin))) {
0
           entry_append(state, slot, entry);
0
+        } else {
0
+          new_values->put(state, bin, entry);
0
         }
0
 
0
         entry = next;
0
@@ -136,25 +128,29 @@ namespace rubinius {
0
     bins = Object::i2n(size);
0
   }
0
 
0
-  OBJECT Hash::find_entry(STATE, hashval hsh) {
0
+  /* Find the entry that has a hash value of +hsh+. Return NULL if nothing
0
+   * found. */
0
+  Tuple* Hash::find_entry(STATE, hashval hsh) {
0
     size_t num = bins->n2i();
0
     size_t bin = find_bin(hsh, num);
0
-    OBJECT entry = values->at(bin);
0
+    Tuple* entry = try_as<Tuple>(values->at(bin));
0
+    if(!entry) return NULL;
0
 
0
-    while(!entry->nil_p()) {
0
+    for(;;) {
0
       INTEGER th = as<Integer>(entry->at(0));
0
       if((hashval)th->n2i() == hsh) {
0
         return entry;
0
       }
0
-      entry = entry->at(3);
0
+
0
+      if((entry = try_as<Tuple>(entry->at(3))) == NULL) return NULL;
0
     }
0
-    return Qnil;
0
+    return NULL;
0
   }
0
 
0
   OBJECT Hash::add(STATE, hashval hsh, OBJECT key, OBJECT data) {
0
-    Tuple* entry = (Tuple*)find_entry(state, hsh);
0
+    Tuple* entry = find_entry(state, hsh);
0
 
0
-    if(!entry->nil_p()) {
0
+    if(entry) {
0
       entry->put(state, 2, data);
0
       return data;
0
     }
0
@@ -171,8 +167,8 @@ namespace rubinius {
0
   }
0
 
0
   OBJECT Hash::get(STATE, hashval hsh) {
0
-    OBJECT entry = find_entry(state, hsh);
0
-    if(!entry->nil_p()) {
0
+    Tuple* entry = find_entry(state, hsh);
0
+    if(entry) {
0
       return entry->at(2);
0
     }
0
 
0
@@ -183,20 +179,20 @@ namespace rubinius {
0
    * Uses +==+ to verify the key in the table matches +key+.
0
    * Return TRUE if key was found, and *value will be filled. */
0
   int Hash::lookup(STATE, OBJECT key, hashval hash, OBJECT *value) {
0
-    OBJECT ent, hk;
0
+    OBJECT hk;
0
 
0
-    ent = find_entry(state, hash);
0
-    if(ent->reference_p()) {
0
-      while((hashval)as<Integer>(ent->at(0))->n2i() == hash) {
0
-        hk = ent->at(1);
0
-        if(hk == key) {
0
-          *value = ent->at(2);
0
-          return TRUE;
0
-        }
0
+    Tuple* ent = find_entry(state, hash);
0
+    if(!ent) return FALSE;
0
 
0
-        ent = ent->at(3);
0
-        if(ent->nil_p()) break;
0
+    while((hashval)as<Integer>(ent->at(0))->n2i() == hash) {
0
+      hk = ent->at(1);
0
+      if(hk == key) {
0
+        *value = ent->at(2);
0
+        return TRUE;
0
       }
0
+
0
+      ent = try_as<Tuple>(ent->at(3));
0
+      if(!ent) break;
0
     }
0
 
0
     return FALSE;
0
@@ -207,20 +203,20 @@ namespace rubinius {
0
    * Return TRUE if key was found, and *value will be filled. */
0
   int Hash::lookup2(STATE, int (*compare)(STATE, OBJECT, OBJECT),
0
       OBJECT key, hashval hash, OBJECT *value) {
0
-    OBJECT ent, hk;
0
+    OBJECT hk;
0
 
0
-    ent = find_entry(state, hash);
0
-    if(ent->reference_p()) {
0
-      while((hashval)as<Integer>(ent->at(0))->n2i() == hash) {
0
-        hk = ent->at(1);
0
-        if(compare(state, hk, key)) {
0
-          *value = ent->at(2);
0
-          return TRUE;
0
-        }
0
+    Tuple* ent = find_entry(state, hash);
0
+    if(!ent) return FALSE;
0
 
0
-        ent = ent->at(3);
0
-        if(ent->nil_p()) break;
0
+    while((hashval)as<Integer>(ent->at(0))->n2i() == hash) {
0
+      hk = ent->at(1);
0
+      if(compare(state, hk, key)) {
0
+        *value = ent->at(2);
0
+        return TRUE;
0
       }
0
+
0
+      ent = try_as<Tuple>(ent->at(3));
0
+      if(!ent) break;
0
     }
0
 
0
     return FALSE;
0
@@ -232,8 +228,8 @@ namespace rubinius {
0
     Tuple* ent;
0
     Tuple* base;
0
 
0
-    base = ent = (Tuple*)find_entry(state, hash);
0
-    if(ent->reference_p()) {
0
+    base = ent = find_entry(state, hash);
0
+    if(ent) {
0
       while((hashval)as<Integer>(ent->at(0))->n2i() == hash) {
0
         hk = ent->at(1);
0
         if(compare(state, hk, key)) {
0
@@ -241,8 +237,8 @@ namespace rubinius {
0
           return;
0
         }
0
 
0
-        ent = (Tuple*)ent->at(3);
0
-        if(ent->nil_p()) break;
0
+        ent = try_as<Tuple>(ent->at(3));
0
+        if(!ent) break;
0
       }
0
 
0
     }
0
@@ -251,14 +247,14 @@ namespace rubinius {
0
       redistribute(state);
0
     }
0
 
0
-    if(base->reference_p()) {
0
-      ent = (Tuple*)entry_new(state, hash, key, value);
0
+    if(base) {
0
+      ent = entry_new(state, hash, key, value);
0
       entry_append(state, base, ent);
0
       entries = Object::i2n(entries->n2i() + 1);
0
       return;
0
     }
0
 
0
-    ent = (Tuple*)entry_new(state, hash, key, value);
0
+    ent = entry_new(state, hash, key, value);
0
     add_entry(state, hash, ent);
0
   }
0
 
0
@@ -268,10 +264,8 @@ namespace rubinius {
0
    */
0
 
0
   OBJECT Hash::get_undef(STATE, hashval hsh) {
0
-    OBJECT entry;
0
-
0
-    entry = find_entry(state, hsh);
0
-    if(RTEST(entry)) {
0
+    Tuple* entry = find_entry(state, hsh);
0
+    if(entry) {
0
       return entry->at(2);
0
     } else {
0
       return Qundef;
0
@@ -313,7 +307,7 @@ namespace rubinius {
0
     return Qnil;
0
   }
0
 
0
-  Hash* Hash::from_tuple(STATE, OBJECT tup) {
0
+  Hash* Hash::from_tuple(STATE, Tuple* tup) {
0
     OBJECT key, val;
0
     int i, fel;
0
 
...
11
12
13
14
15
16
17
18
19
20
 
 
 
 
 
 
 
21
22
23
24
25
26
27
 
 
 
28
29
 
30
31
32
...
38
39
40
41
 
42
43
44
45
46
47
 
 
 
 
 
 
 
48
 
 
 
49
50
51
...
11
12
13
 
 
 
 
 
 
 
14
15
16
17
18
19
20
21
22
23
24
 
 
 
25
26
27
28
 
29
30
31
32
...
38
39
40
 
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
0
@@ -11,22 +11,22 @@ namespace rubinius {
0
     const static size_t fields = 7;
0
     const static object_type type = HashType;
0
 
0
-    OBJECT instance_variables;
0
-    OBJECT keys;
0
-    Tuple* values;
0
-    FIXNUM bins;
0
-    FIXNUM entries;
0
-    OBJECT default_value;
0
-    OBJECT default_proc;
0
+    OBJECT __ivars__; // slot
0
+    OBJECT keys; // slot
0
+    Tuple* values; // slot
0
+    FIXNUM bins; // slot
0
+    FIXNUM entries; // slot
0
+    OBJECT default_value; // slot
0
+    OBJECT default_proc; // slot
0
 
0
     static Hash* create(STATE, size_t size = HASH_MINSIZE);
0
     void   setup(STATE, size_t size);
0
     Hash*  dup(STATE);
0
-    static OBJECT entry_new(STATE, hashval hsh, OBJECT key, OBJECT data);
0
-    static OBJECT entry_append(STATE, OBJECT top, OBJECT nxt);
0
-    OBJECT add_entry(STATE, hashval hsh, OBJECT ent);
0
+    static Tuple* entry_new(STATE, hashval hsh, OBJECT key, OBJECT data);
0
+    static Tuple* entry_append(STATE, Tuple* top, Tuple* nxt);
0
+    OBJECT add_entry(STATE, hashval hsh, Tuple* ent);
0
     void   redistribute(STATE);
0
-    OBJECT find_entry(STATE, hashval hsh);
0
+    Tuple* find_entry(STATE, hashval hsh);
0
     OBJECT add(STATE, hashval hsh, OBJECT key, OBJECT data);
0
     OBJECT set(STATE, OBJECT key, OBJECT val);
0
     OBJECT get(STATE, hashval hsh);
0
@@ -38,14 +38,24 @@ namespace rubinius {
0
     OBJECT get_undef(STATE, hashval hsh);
0
     OBJECT remove(STATE, hashval hsh);
0
 
0
-    static Hash*  from_tuple(STATE, OBJECT tup);
0
+    static Hash*  from_tuple(STATE, Tuple* tup);
0
     static Tuple* csm_new(STATE);
0
     static OBJECT csm_find(STATE, Tuple* csm, OBJECT key);
0
     static OBJECT csm_add(STATE, Tuple* csm, OBJECT key, OBJECT val);
0
     static Hash*  csm_into_hash(STATE, Tuple* csm);
0
     static LookupTable* csm_into_lookuptable(STATE, Tuple* csm);
0
 
0
+    class Info : public TypeInfo {
0
+    public:
0
+      Info(object_type type) : TypeInfo(type) { }
0
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
0
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
0
+    };
0
+
0
   };
0
+
0
+#define HASH_MAX_DENSITY 0.75
0
+#define hash_redistribute_p(hash) (hash->entries->n2i() >= HASH_MAX_DENSITY * hash->bins->n2i())
0
 };
0
 
0
 #endif
...
6
7
8
9
 
10
11
12
13
 
 
14
15
16
...
23
24
25
 
 
 
 
 
26
...
6
7
8
 
9
10
11
 
 
12
13
14
15
16
...
23
24
25
26
27
28
29
30
31
0
@@ -6,11 +6,11 @@
0
 
0
 namespace rubinius {
0
   void IO::init(STATE) {
0
-    GO(iobuffer).set(state->new_class("Buffer", G(object), IO::Buffer::fields, G(io)));
0
+    GO(iobuffer).set(state->new_class("Buffer", G(object), IOBuffer::fields, G(io)));
0
   }
0
 
0
-  IO::Buffer* IO::Buffer::create(STATE, size_t bytes) {
0
-    IO::Buffer* buf = (IO::Buffer*)state->new_object(G(iobuffer));
0
+  IOBuffer* IOBuffer::create(STATE, size_t bytes) {
0
+    IOBuffer* buf = (IOBuffer*)state->new_object(G(iobuffer));
0
     SET(buf, storage, ByteArray::create(state, bytes));
0
     SET(buf, total, Object::i2n(bytes));
0
     SET(buf, used, Object::i2n(0));
0
@@ -23,4 +23,9 @@ namespace rubinius {
0
     SET(io, descriptor, Object::i2n(state, fd));
0
     return io;
0
   }
0
+
0
+  void IO::initialize(STATE, int fd, char* mode) {
0
+    SET(this, descriptor, Object::i2n(state, fd));
0
+    SET(this, mode, String::create(state, mode));
0
+  }
0
 };
...
1
2
3
4
5
6
 
 
 
7
8
9
10
 
11
12
13
...
1
2
3
 
 
 
4
5
6
7
8
9
 
10
11
12
13
0
@@ -1,13 +1,13 @@
0
 #include "builtin.hpp"
0
 
0
 namespace rubinius {
0
-  ISeq* ISeq::create(STATE, size_t instructions) {
0
-    ISeq* is = (ISeq*)state->new_object(G(iseq));
0
-    is->instructions = Tuple::create(state, instructions);
0
+  InstructionSequence* InstructionSequence::create(STATE, size_t instructions) {
0
+    InstructionSequence* is = (InstructionSequence*)state->new_object(G(iseq));
0
+    is->opcodes = Tuple::create(state, instructions);
0
     return is;
0
   }
0
 
0
-  void ISeq::post_marshal(STATE) {
0
+  void InstructionSequence::post_marshal(STATE) {
0
 
0
   }
0
 
...
4
5
6
7
 
8
9
 
10
11
12
13
 
 
 
14
15
16
 
 
 
 
 
 
 
 
17
18
19
...
4
5
6
 
7
8
 
9
10
11
 
 
12
13
14
15
16
 
17
18
19
20
21
22
23
24
25
26
27
0
@@ -4,16 +4,24 @@
0
 #include "objects.hpp"
0
 
0
 namespace rubinius {
0
-  class ISeq : public BuiltinType {
0
+  class InstructionSequence : public BuiltinType {
0
   public:
0
-    const static size_t fields = 2;
0
+    const static size_t fields = 3;
0
     const static object_type type = ISeqType;
0
 
0
-    OBJECT instance_variables;
0
-    Tuple* instructions;
0
+    OBJECT __ivars__; // slot
0
+    Tuple* opcodes; // slot
0
+    FIXNUM stack_depth; // slot
0
 
0
     void post_marshal(STATE);
0
-    static ISeq* create(STATE, size_t instructions);
0
+    static InstructionSequence* create(STATE, size_t instructions);
0
+
0
+    class Info : public TypeInfo {
0
+    public:
0
+      Info(object_type type) : TypeInfo(type) { }
0
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
0
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
0
+    };
0
 
0
 #include "gen/iseq_instruction_names.hpp"
0
   };
...
10
11
12
13
 
 
 
14
15
16
17
18
19
 
20
21
22
23
24
25
26
 
27
28
 
29
30
31
...
37
38
39
40
 
41
42
43
44
45
 
46
47
48
...
60
61
62
63
64
 
 
65
66
67
68
 
69
70
71
...
79
80
81
82
83
84
 
 
 
85
86
87
...
98
99
100
101
 
102
103
104
...
107
108
109
110
 
111
112
113
...
10
11
12
 
13
14
15
16
17
18
19
20
 
21
22
23
24
25
26
27
 
28
29
 
30
31
32
33
...
39
40
41
 
42
43
44
45
46
 
47
48
49
50
...
62
63
64
 
 
65
66
67
68
69
 
70
71
72
73
...
81
82
83
 
 
 
84
85
86
87
88
89
...
100
101
102
 
103
104
105
106
...
109
110
111
 
112
113
114
115
0
@@ -10,22 +10,24 @@ namespace rubinius {
0
     cls->set_object_type(ListType);
0
 
0
     GO(list_node).set(state->new_class("Node", G(object),
0
-                                                List::Node::fields, cls));
0
+                                                ListNode::fields, cls));
0
+
0
+    G(list_node)->set_object_type(ListNodeType);
0
   }
0
 
0
   /* Create a new List object, containing no elements. */
0
   List* List::create(STATE) {
0
     List* list = (List*)state->new_object(G(list));
0
-    list->count = Object::i2n(0);
0
+    SET(list, count, Object::i2n(0));
0
 
0
     return list;
0
   }
0
 
0
   /* Append +obj+ to the current List. */
0
   void List::append(STATE, OBJECT obj) {
0
-    List::Node* node = (List::Node*)state->new_object(G(list_node));
0
+    ListNode* node = (ListNode*)state->new_object(G(list_node));
0
     SET(node, object, obj);
0
-    List::Node* cur_last = last;
0
+    ListNode* cur_last = last;
0
 
0
     if(!cur_last->nil_p()) {
0
       SET(cur_last, next, node);
0
@@ -37,12 +39,12 @@ namespace rubinius {
0
       SET(this, first, node);
0
     }
0
 
0
-    count = Object::i2n(state, count->n2i() + 1);
0
+    SET(this, count, Object::i2n(state, count->n2i() + 1));
0
   }
0
 
0
   /* Return the +index+ numbered element from the beginning. */
0
   OBJECT List::locate(STATE, size_t index) {
0
-    Node* cur = first;
0
+    ListNode* cur = first;
0
 
0
     while(index > 0) {
0
       if(cur->nil_p()) return Qnil;
0
@@ -60,12 +62,12 @@ namespace rubinius {
0
   OBJECT List::shift(STATE) {
0
     if(empty_p()) return Qnil;
0
 
0
-    count = Object::i2n(state, count->n2i() - 1);
0
-    List::Node* n = first;
0
+    SET(this, count, Object::i2n(state, count->n2i() - 1));
0
+    ListNode* n = first;
0
     SET(this, first, first->next);
0
 
0
     if(last == n) {
0
-      last = (Node*)Qnil;
0
+      SET(this, last, Qnil);
0
     }
0
 
0
     return n->object;
0
@@ -79,9 +81,9 @@ namespace rubinius {
0
 
0
     size_t deleted = 0, counted = 0;
0
 
0
-    Node* node = first;
0
-    Node* lst =  (Node*)Qnil;
0
-    Node* nxt =  (Node*)Qnil;
0
+    ListNode* node = first;
0
+    ListNode* lst =  (ListNode*)Qnil;
0
+    ListNode* nxt =  (ListNode*)Qnil;
0
 
0
     while(!node->nil_p()) {
0
       nxt = node->next;
0
@@ -98,7 +100,7 @@ namespace rubinius {
0
           SET(this, last, lst);
0
         }
0
 
0
-        lst = (Node*)Qnil;
0
+        lst = (ListNode*)Qnil;
0
       } else {
0
         counted++;
0
         lst = node;
0
@@ -107,7 +109,7 @@ namespace rubinius {
0
       node = nxt;
0
     }
0
 
0
-    count = Object::i2n(state, counted);
0
+    SET(this, count, Object::i2n(state, counted));
0
 
0
     return deleted;
0
   }
...
5
6
7
8
9
 
 
10
11
12
 
 
13
14
 
 
15
16
17
 
 
 
 
 
18
19
20
 
 
 
 
 
 
 
21
22
23
24
25
 
 
 
 
26
27
28
...
40
41
42
 
 
 
 
 
 
 
 
43
44
45
...
5
6
7
 
 
8
9
10
 
 
11
12
13
 
14
15
16
 
 
17
18
19
20
21
22
 
 
23
24
25
26
27
28
29
30
31
 
 
 
32
33
34
35
36
37
38
...
50
51
52
53
54
55
56
57
58
59
60
61
62
63
0
@@ -5,24 +5,34 @@
0
 
0
 namespace rubinius {
0
 
0
-  class List : public BuiltinType {
0
-    public:
0
+  class ListNode : public BuiltinType {
0
+  public:
0
 
0
-    class Node : public BuiltinType {
0
-      public:
0
+    const static size_t fields = 2;
0
+    const static object_type type = ListNodeType;
0
 
0
-      const static size_t fields = 2;
0
+    OBJECT object; // slot
0
+    ListNode* next; // slot
0
 
0
-      OBJECT object;
0
-      Node* next;
0
+    class Info : public TypeInfo {
0
+    public:
0
+      Info(object_type type) : TypeInfo(type) { }
0
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
0
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
0
     };
0
-      
0
-    const static size_t fields = 3;
0
+
0
+  };
0
+
0
+  class List : public BuiltinType {
0
+  public:
0
+
0
+    const static size_t fields = 4;
0
     const static object_type type = ListType;
0
 
0
-    INTEGER count;
0
-    Node* first;
0
-    Node* last;
0
+    OBJECT __ivars__; // slot
0
+    INTEGER count; // slot
0
+    ListNode* first; // slot
0
+    ListNode* last; // slot
0
 
0
     /* Returns true if the List is empty, contains no elements. */
0
     bool empty_p() {
0
@@ -40,6 +50,14 @@ namespace rubinius {
0
     OBJECT shift(STATE);
0
     OBJECT locate(STATE, size_t index);
0
     size_t remove(STATE, OBJECT obj);
0
+
0
+    class Info : public TypeInfo {
0
+    public:
0
+      Info(object_type type) : TypeInfo(type) { }
0
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
0
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
0
+    };
0
+
0
   };
0
 
0
 };
...
52
53
54
55
 
56
57
 
58
59
60
...
71
72
73
74
75
76
 
 
 
77
78
 
79
80
 
81
82
83
...
96
97
98
99
 
100
101
 
102
103
104
...
149
150
151
152
 
153
154
 
155
156
157
158
 
159
160
 
161
162
163
164
 
165
166
 
167
168
169
170
171
172
173
174
175
 
 
176
177
178
179
180
181
182
183
 
 
184
185
186
...
195
196
197
198
199
200
201
 
 
202
203
204
...
247
248
249
250
 
251
252
253
254
255
 
256
257
258
259
 
260
261
 
 
262
263
264
265
266
267
268
 
269
270
 
271
272
 
273
274
275
276
277
278
 
279
280
281
...
283
284
285
286
 
287
288
289
...
291
292
293
294
 
295
296
297
298
 
299
300
301
...
52
53
54
 
55
56
 
57
58
59
60
...
71
72
73
 
 
 
74
75
76
77
 
78
79
 
80
81
82
83
...
96
97
98
 
99
100
 
101
102
103
104
...
149
150
151
 
152
153
 
154
155
156
157
 
158
159
 
160
161
162
163
 
164
165
 
166
167
168
169
 
 
 
 
 
 
170
171
172
173
174
175
 
 
 
 
176
177
178
179
180
...
189
190
191
 
 
 
 
192
193
194
195
196
...
239
240
241
 
242
243
 
 
 
 
244
245
246
247
 
248
249
 
250
251
252
253
254
255
256
257
 
258
259
 
260
261
 
262
263
264
265
266
267
 
268
269
270
271
...
273
274
275
 
276
277
278
279
...
281
282
283
 
284
285
286
287
 
288
289
290
291
0
@@ -52,9 +52,9 @@ namespace rubinius {
0
     state->om->set_class(dup, class_object(state));
0
     size_t num = entries->n2i();
0
 
0
-    Array* entries = (Array*)all_entries(state);
0
+    Array* entries = all_entries(state);
0
     for(i = 0; i < num; i++) {
0
-      OBJECT entry = entries->get(state, i);
0
+      Tuple* entry = as<Tuple>(entries->get(state, i));
0
       OBJECT key =   entry->at(0);
0
       OBJECT value = entry->at(1);
0
       dup->store(state, key, value);
0
@@ -71,13 +71,13 @@ namespace rubinius {
0
     return tup;
0
   }
0
 
0
-  OBJECT LookupTable::entry_append(STATE, OBJECT top, OBJECT nxt) {
0
-    Tuple* cur = (Tuple*)top->at(2);
0
-    Tuple* last = (Tuple*)top;
0
+  OBJECT LookupTable::entry_append(STATE, Tuple* top, OBJECT nxt) {
0
+    Tuple* cur = try_as<Tuple>(top->at(2));
0
+    Tuple* last = top;
0
 
0
-    while(!cur->nil_p()) {
0
+    while(cur) {
0
       last = cur;
0
-      cur = (Tuple*)cur->at(2);
0
+      cur = try_as<Tuple>(cur->at(2));
0
     }
0
 
0
     last->put(state, 2, nxt);
0
@@ -96,9 +96,9 @@ namespace rubinius {
0
         entry->put(state, 2, Qnil);
0
 
0
         size_t bin = find_bin(key_hash(entry->at(0)), size);
0
-        OBJECT slot = new_values->at(bin);
0
+        Tuple* slot = try_as<Tuple>(new_values->at(bin));
0
 
0
-        if(slot->nil_p()) {
0
+        if(!slot) {
0
           new_values->put(state, bin, entry);
0
         } else {
0
           entry_append(state, slot, entry);
0
@@ -149,38 +149,32 @@ namespace rubinius {
0
     return val;
0
   }
0
 
0
-  OBJECT LookupTable::find_entry(STATE, OBJECT key) {
0
+  Tuple* LookupTable::find_entry(STATE, OBJECT key) {
0
     unsigned int bin;
0
-    OBJECT entry;
0
+    Tuple* entry;
0
 
0
     key_to_sym(key);
0
     bin = find_bin(key_hash(key), bins->n2i());
0
-    entry = values->at(bin);
0
+    entry = try_as<Tuple>(values->at(bin));
0
 
0
-    while(!entry->nil_p()) {
0
+    while(entry) {
0
       if(entry->at(0) == key) {
0
         return entry;
0
       }
0
-      entry = entry->at(2);
0
+      entry = try_as<Tuple>(entry->at(2));
0
     }
0
-    return Qnil;
0
+    return NULL;
0
   }
0
 
0
   OBJECT LookupTable::fetch(STATE, OBJECT key) {
0
-    OBJECT entry;
0
-
0
-    entry = find_entry(state, key);
0
-    if(!entry->nil_p()) {
0
-      return entry->at(1);
0
-    }
0
+    Tuple* entry = find_entry(state, key);
0
+    if(entry) return entry->at(1);
0
     return Qnil;
0
   }
0
 
0
   OBJECT LookupTable::fetch(STATE, OBJECT key, bool* found) {
0
-    OBJECT entry;
0
-
0
-    entry = find_entry(state, key);
0
-    if(!entry->nil_p()) {
0
+    Tuple* entry = find_entry(state, key);
0
+    if(entry) {
0
       *found = true;
0
       return entry->at(1);
0
     }
0
@@ -195,10 +189,8 @@ namespace rubinius {
0
    * in cpu.c in e.g. cpu_const_get_in_context.
0
    */
0
   OBJECT LookupTable::find(STATE, OBJECT key) {
0
-    OBJECT entry;
0
-
0
-    entry = find_entry(state, key);
0
-    if(!entry->nil_p()) {
0
+    Tuple* entry = find_entry(state, key);
0
+    if(entry) {
0
       return entry->at(1);
0
     }
0
     return Qundef;
0
@@ -247,35 +239,33 @@ namespace rubinius {
0
   }
0
 
0
   OBJECT LookupTable::has_key(STATE, OBJECT key) {
0
-    OBJECT entry;
0
+    Tuple* entry = find_entry(state, key);
0
 
0
-    entry = find_entry(state, key);
0
-    if(!entry->nil_p()) {
0
-      return Qtrue;
0
-    }
0
+    if(entry) return Qtrue;
0
     return Qfalse;
0
   }
0
 
0
-  Array* LookupTable::collect(STATE, LookupTable* tbl, OBJECT (*action)(STATE, OBJECT)) {
0
+  Array* LookupTable::collect(STATE, LookupTable* tbl, OBJECT (*action)(STATE, Tuple*)) {
0
     size_t i, j;
0
-    OBJECT values, entry;
0
+    Tuple* values;
0
+    Tuple* entry;
0
 
0
     Array* ary = Array::create(state, tbl->entries->n2i());
0
     size_t num_bins = tbl->bins->n2i();
0
     values = tbl->values;
0
 
0
     for(i = j = 0; i < num_bins; i++) {
0
-      entry = values->at(i);
0
+      entry = try_as<Tuple>(values->at(i));
0
 
0
-      while(!entry->nil_p()) {
0
+      while(entry) {
0
         ary->set(state, j++, action(state, entry));
0
-        entry = entry->at(2);
0
+        entry = try_as<Tuple>(entry->at(2));
0
       }
0
     }
0
     return ary;
0
   }
0
 
0
-  OBJECT LookupTable::get_key(STATE, OBJECT entry) {
0
+  OBJECT LookupTable::get_key(STATE, Tuple* entry) {
0
     return entry->at(0);
0
   }
0
 
0
@@ -283,7 +273,7 @@ namespace rubinius {
0
     return collect(state, this, get_key);
0
   }
0
 
0
-  OBJECT LookupTable::get_value(STATE, OBJECT entry) {
0
+  OBJECT LookupTable::get_value(STATE, Tuple* entry) {
0
     return entry->at(1);
0
   }
0
 
0
@@ -291,11 +281,11 @@ namespace rubinius {
0
     return collect(state, this, get_value);
0
   }
0
 
0
-  OBJECT LookupTable::get_entry(STATE, OBJECT entry) {
0
+  OBJECT LookupTable::get_entry(STATE, Tuple* entry) {
0
     return entry;
0
   }
0
 
0
-  OBJECT LookupTable::all_entries(STATE) {
0
+  Array* LookupTable::all_entries(STATE) {
0
     return collect(state, this, get_entry);
0
   }
0
 
...
114
115
116
117
118
 
 
119
120
121
...
231
232
233
234
235
236
237
 
 
238
239
240
241
 
 
242
243
 
 
 
244
245
 
 
 
246
247
248
 
249
250
251
252
253
254
255
256
 
257
258
259
...
266
267
268
269
 
270
271
272
 
 
273
274
275
276
277
278
279
 
 
280
281
282
 
 
283
284
285
...
287
288
289
290
 
291
292
293
294
 
 
295
296
297
298
299
300
301
 
 
302
303
304
305
306
 
307
308
309
 
 
310
311
312
...
323
324
325
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
326
...
114
115
116
 
 
117
118
119
120
121
...
231
232
233
 
 
 
 
234
235
236
237
 
 
238
239
240
 
241
242
243
244
 
245
246
247
248
249
 
250
251
252
 
 
 
 
 
 
253
254
255
256
...
263
264
265
 
266
267
 
 
268
269
270
271
272
273
274
 
 
275
276
277
 
 
278
279
280
281
282
...
284
285
286
 
287
288
289
 
 
290
291
292
293
294
295
296
 
 
297
298
299
300
301
302
 
303
304
305
 
306
307
308
309
310
...
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
0
@@ -114,8 +114,8 @@ namespace rubinius {
0
   Class* Object::class_object(STATE) {
0
     if(reference_p()) {
0
       Class* cls = klass;
0
-      while(!cls->nil_p() && !kind_of<Class>(cls)) {
0
-        cls = (Class*)cls->superclass;
0
+      while(!cls->nil_p() && !instance_of<Class>(cls)) {
0
+        cls = as<Class>(cls->superclass);
0
       }
0
 
0
       return cls;
0
@@ -231,29 +231,26 @@ namespace rubinius {
0
     /* Implements the external ivars table for objects that don't
0
        have their own space for ivars. */
0
     if(!reference_p()) {
0
-      LookupTable* tbl = (LookupTable*)G(external_ivars)->fetch(state, this);
0
-      if(!tbl->nil_p()) {
0
-        return tbl->fetch(state, sym);
0
-      }
0
+      LookupTable* tbl = try_as<LookupTable>(G(external_ivars)->fetch(state, this));
0
+      if(tbl) return tbl->fetch(state, sym);
0
       return Qnil;
0
     } else if(!has_ivars_p()) {
0
-      MetaClass* meta = (MetaClass*)metaclass(state);
0
-      LookupTable* tbl = (LookupTable*)meta->has_ivars;
0
+      MetaClass* meta = as<MetaClass>(metaclass(state));
0
+      LookupTable* tbl = try_as<LookupTable>(meta->has_ivars);
0
 
0
-      if(tbl->nil_p()) return Qnil;
0
+      if(tbl) return tbl->fetch(state, sym);
0
+      return Qnil;
0
+    }
0
 
0
-      return tbl->fetch(state, sym);
0
+    /* It's a tuple, use csm */
0
+    if(Tuple* tup = try_as<Tuple>(((NormalObject*)this)->instance_variables)) {
0
+      return Hash::csm_find(state, tup, sym);
0
     }
0
 
0
-    tbl = (LookupTable*)((NormalObject*)this)->instance_variables;
0
+    tbl = try_as<LookupTable>(((NormalObject*)this)->instance_variables);
0
 
0
     /* No table, no ivar! */
0
-    if(tbl->nil_p()) return Qnil;
0
-
0
-    /* It's a tuple, use csm */
0
-    if(kind_of<Tuple>(tbl)) {
0
-      return Hash::csm_find(state, (Tuple*)tbl, sym);
0
-    }
0
+    if(!tbl) return Qnil;
0
 
0
     /* It's a normal hash, no problem. */
0
     val = tbl->fetch(state, sym);
0
@@ -266,20 +263,20 @@ namespace rubinius {
0
     /* Implements the external ivars table for objects that don't
0
        have their own space for ivars. */
0
     if(!reference_p()) {
0
-      tbl = (LookupTable*)G(external_ivars)->fetch(state, this);
0
+      tbl = try_as<LookupTable>(G(external_ivars)->fetch(state, this));
0
 
0
-      if(tbl->nil_p()) {
0
-        tbl = (LookupTable*)LookupTable::create(state);
0
+      if(!tbl) {
0
+        tbl = LookupTable::create(state);
0
         G(external_ivars)->store(state, this, tbl);
0
       }
0
       tbl->store(state, sym, val);
0
       return val;
0
     } else if(!has_ivars_p()) {
0
-      MetaClass* meta = (MetaClass*)metaclass(state);
0
-      LookupTable* tbl = (LookupTable*)meta->has_ivars;
0
+      MetaClass* meta = as<MetaClass>(metaclass(state));
0
+      tbl = try_as<LookupTable>(meta->has_ivars);
0
 
0
-      if(tbl->nil_p()) {
0
-        tbl = (LookupTable*)LookupTable::create(state);
0
+      if(!tbl) {
0
+        tbl = LookupTable::create(state);
0
         SET(meta, has_ivars, tbl);
0
       }
0
 
0
@@ -287,26 +284,27 @@ namespace rubinius {
0
       return val;
0
     }
0
 
0
-    tbl = (LookupTable*)((NormalObject*)this)->instance_variables;
0
+    OBJECT ivars = ((NormalObject*)this)->instance_variables;
0
 
0
     /* Lazy creation of hash to store instance variables. */
0
-    if(tbl->nil_p()) {
0
-      Tuple* tup = (Tuple*)Hash::csm_new(state);
0
+    if(ivars->nil_p()) {
0
+      Tuple* tup = Hash::csm_new(state);
0
       SET((NormalObject*)this, instance_variables, tup);
0
       Hash::csm_add(state, tup, sym, val);
0
       return val;
0
     }
0
 
0
-    if(kind_of<Tuple>(tbl)) {
0
-      if(Hash::csm_add(state, (Tuple*)tbl, sym, val) == Qtrue) {
0
+    if(Tuple* tup = try_as<Tuple>(ivars)) {
0
+      if(Hash::csm_add(state, tup, sym, val) == Qtrue) {
0
         return val;
0
       }
0
       /* csm_add said false, meaning there is no room. We convert
0
          the csm into a normal hash and use it from now on. */
0
-      tbl = (LookupTable*)Hash::csm_into_lookuptable(state, (Tuple*)tbl);
0
+      tbl = Hash::csm_into_lookuptable(state, (Tuple*)tbl);
0
       SET((NormalObject*)this, instance_variables, tbl);
0
     }
0
-    tbl->store(state, sym, val);
0
+    
0
+    as<LookupTable>(ivars)->store(state, sym, val);
0
     return val;
0
   }
0
 
0
@@ -323,4 +321,24 @@ namespace rubinius {
0
   void Object::cleanup(STATE) {
0
     state->om->find_type_info(this)->cleanup(this);
0
   }
0
+
0
+  void Object::copy_flags(STATE, OBJECT source) {
0
+    this->obj_type        = source->obj_type;
0
+    this->CanStoreIvars   = source->CanStoreIvars;
0
+    this->StoresBytes     = source->StoresBytes;
0
+    this->RequiresCleanup = source->RequiresCleanup;
0
+    this->IsBlockContext  = source->IsBlockContext;
0
+    this->IsMeta          = source->IsMeta;
0
+  }
0
+    
0
+  // 'virtual' methods. They dispatch to the object's TypeInfo
0
+  // object to perform the work.
0
+  OBJECT Object::get_field(STATE, size_t index) {
0
+    return state->om->type_info[obj_type]->get_field(state, this, index);
0
+  }
0
+
0
+  void Object::set_field(STATE, size_t index, OBJECT val) {
0
+    state->om->type_info[obj_type]->set_field(state, this, index, val);
0
+  }
0
+
0
 }
...
42
43
44
45
 
46
47
48
...
42
43
44
 
45
46
47
48
0
@@ -42,7 +42,7 @@ namespace rubinius {
0
 
0
     GO(matchdata).set(state->new_class("MatchData", G(object), 0));
0
 
0
-    state->add_type_info(new RegexpData::Info(G(regexpdata)));
0
+    state->add_type_info(new RegexpData::Info(RegexpData::type));
0
   }
0
 
0
   char *Regexp::version(STATE) {
...
1
2
3
4
5
6
7
...
10
11
12
13
 
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 
 
 
 
39
40
41
...
45
46
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
50
51
...
1
2
3
 
4
5
6
...
9
10
11
 
12
13
14
15
 
 
 
 
 
16
 
 
 
 
 
 
 
17
18
19
20
21
 
 
 
 
22
23
24
25
26
27
28
...
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
0
@@ -1,7 +1,6 @@
0
 #ifndef RBX_REGEXP_HPP
0
 #define RBX_REGEXP_HPP
0
 
0
-
0
 namespace rubinius {
0
   class RegexpData : public BuiltinType {
0
     public:
0
@@ -10,32 +9,20 @@ namespace rubinius {
0
 
0
     class Info : public TypeInfo {
0
     public:
0
-      Info(Class* cls) : TypeInfo(cls) { }
0
+      Info(object_type type) : TypeInfo(type) { }
0
       virtual void cleanup(OBJECT obj);
0
     };
0
   };
0
-  
0
-  class MatchData : public BuiltinType {
0
-    public:
0
-    const static size_t fields = 5;
0
-    const static object_type type = MatchDataType;
0
 
0
-    OBJECT instance_variables;
0
-    OBJECT source;
0
-    OBJECT regexp;
0
-    OBJECT full;
0
-    OBJECT region;
0
-  };
0
-  
0
   class Regexp : public BuiltinType {
0
     public:
0
     const static size_t fields = 4;
0
     const static object_type type = RegexpType;
0
 
0
-    OBJECT instance_variables;
0
-    OBJECT source;
0
-    OBJECT data;
0
-    OBJECT names;
0
+    OBJECT __ivars__; // slot
0
+    String* source; // slot
0
+    RegexpData* data; // slot
0
+    Hash* names; // slot
0
 
0
     static void cleanup(STATE, OBJECT data);
0
     static void init(STATE);
0
@@ -45,7 +32,34 @@ namespace rubinius {
0
     OBJECT options(STATE);
0
     OBJECT match_region(STATE, String* string, INTEGER start, INTEGER end, OBJECT forward);
0
 
0
+    class Info : public TypeInfo {
0
+    public:
0
+      Info(object_type type) : TypeInfo(type) { }
0
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
0
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
0
+    };
0
+
0
+  };
0
+
0
+  class MatchData : public BuiltinType {
0
+    public:
0
+    const static size_t fields = 5;
0
+    const static object_type type = MatchDataType;
0
+
0
+    OBJECT __ivars__; // slot
0
+    String* source; // slot
0
+    Regexp* regexp; // slot
0
+    Tuple* full; // slot
0
+    Tuple* region; // slot
0
+
0
+    class Info : public TypeInfo {
0
+    public:
0
+      Info(object_type type) : TypeInfo(type) { }
0
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
0
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
0
+    };
0
   };
0
+
0
 }
0
 
0
 #endif
...
10
11
12
13
 
 
14
15
16
 
 
 
17
18
19
...
24
25
26
 
 
 
 
 
 
 
27
28
29
...
10
11
12
 
13
14
15
 
 
16
17
18
19
20
21
...
26
27
28
29
30
31
32
33
34
35
36
37
38
0
@@ -10,10 +10,12 @@ namespace rubinius {
0
   class Selector : public BuiltinType {
0
     public:
0
 
0
-    static const size_t fields = 2;
0
+    static const size_t fields = 3;
0
+    static const object_type type = SelectorType;
0
 
0
-    OBJECT name;
0
-    Array* send_sites;
0
+    OBJECT __ivars__; // slot
0
+    SYMBOL name; // slot
0
+    Array* send_sites; // slot
0
 
0
     static void init(STATE);
0
     static Selector* create(STATE, OBJECT name);
0
@@ -24,6 +26,13 @@ namespace rubinius {
0
     void   clear(STATE);
0
     bool   includes_p(STATE, SendSite* ss);
0
 
0
+    class Info : public TypeInfo {
0
+    public:
0
+      Info(object_type type) : TypeInfo(type) { }
0
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
0
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
0
+    };
0
+
0
   };
0
 };
0
 
...
52
53
54
55
 
56
57
58
...
64
65
66
67
 
68
69
70
...
52
53
54
 
55
56
57
58
...
64
65
66
 
67
68
69
70
0
@@ -52,7 +52,7 @@ namespace rubinius {
0
   bool HierarchyResolver::resolve(STATE, Message& msg) {
0
     Module* module = msg.lookup_from;
0
     OBJECT entry;
0
-    CompiledMethod::Visibility* vis;
0
+    MethodVisibility* vis;
0
 
0
     do {
0
       entry = module->method_table->fetch(state, msg.name);
0
@@ -64,7 +64,7 @@ namespace rubinius {
0
        * (eg. undef_method) */
0
       if(entry == Qfalse) return false;
0
 
0
-      vis = try_as<CompiledMethod::Visibility>(entry);
0
+      vis = try_as<MethodVisibility>(entry);
0
 
0
       /* If this was a private send, then we can handle use
0
        * any method seen. */
...
45
46
47
48
 
49
50
51
...
76
77
78
79
80
 
 
81
82
83
...
91
92
93
94
95
 
 
96
97
98
...
100
101
102
103
104
 
 
105
106
107
...
116
117
118
119
120
 
 
121
122
123
...
135
136
137
138
139
 
 
140
141
142
...
45
46
47
 
48
49
50
51
...
76
77
78
 
 
79
80
81
82
83
...
91
92
93
 
 
94
95
96
97
98
...
100
101
102
 
 
103
104
105
106
107
...
116
117
118
 
 
119
120
121
122
123
...
135
136
137
 
 
138
139
140
141
142
0
@@ -45,7 +45,7 @@ namespace rubinius {
0
     size_t sz = size(state);
0
 
0
     hashval h = hash_str(bp, sz);
0
-    hash = Object::ui2n(state, h);
0
+    SET(this, hash, Object::ui2n(state, h));
0
 
0
     return h;
0
   }
0
@@ -76,8 +76,8 @@ namespace rubinius {
0
   }
0
 
0
   int String::string_equal_p(STATE, OBJECT a, OBJECT b) {
0
-    String* self = (String*)a;
0
-    String* other = (String*)b;
0
+    String* self = as<String>(a);
0
+    String* other = as<String>(b);
0
 
0
     if(self->bytes != other->bytes) return FALSE;
0
     if(strcmp(self->byte_address(state), other->byte_address(state))) {
0
@@ -91,8 +91,8 @@ namespace rubinius {
0
     String* ns;
0
 
0
     ns = (String*)dup(state);
0
-    ns->shared = Qtrue;
0
-    shared = Qtrue;
0
+    SET(ns, shared, Qtrue);
0
+    SET(this, shared, Qtrue);
0
 
0
     state->om->set_class(ns, class_object(state));
0
 
0
@@ -100,8 +100,8 @@ namespace rubinius {
0
   }
0
 
0
   void String::unshare(STATE) {
0
-    data = data->dup(state);
0
-    shared = Qfalse;
0
+    SET(this, data, as<ByteArray>(data->dup(state)));
0
+    SET(this, shared, Qfalse);
0
   }
0
 
0
   String* String::append(STATE, String* other) {
0
@@ -116,8 +116,8 @@ namespace rubinius {
0
     d2->bytes[new_size] = 0;
0
 
0
     num_bytes = Object::i2n(state, new_size);
0
-    data = d2;
0
-    hash = Qnil;
0
+    SET(this, data, d2);
0
+    SET(this, hash, Qnil);
0
 
0
     return this;
0
   }
0
@@ -135,8 +135,8 @@ namespace rubinius {
0
     d2->bytes[new_size] = 0;
0
 
0
     num_bytes = Object::i2n(state, new_size);
0
-    data = d2;
0
-    hash = Qnil;
0
+    SET(this, data, d2);
0
+    SET(this, hash, Qnil);
0
 
0
     return this;
0
   }
...
4
5
6
7
 
8
9
10
11
12
13
14
15
16
17
18
19
 
 
 
 
 
 
 
20
21
22
...
30
31
32
33
34
35
36
37
38
39
40
...
55
56
57
 
 
 
 
 
 
 
58
59
60
...
4
5
6
 
7
8
9
10
11
12
13
 
 
 
 
 
 
14
15
16
17
18
19
20
21
22
23
...
31
32
33
 
 
 
 
 
34
35
36
...
51
52
53
54
55
56
57
58
59
60
61
62
63
0
@@ -4,19 +4,20 @@
0
 namespace rubinius {
0
   class String : public BuiltinType {
0
     public:
0
-    const static size_t fields = 6;
0
+    const static size_t fields = 7;
0
     const static object_type type = StringType;
0
 
0
     static bool is_a(OBJECT obj) {
0
       return obj->reference_p() && obj->obj_type == StringType;
0
     }
0
 
0
-    INTEGER num_bytes;
0
-    OBJECT characters;
0
-    OBJECT encoding;
0
-    OBJECT data;
0
-    OBJECT hash;
0
-    OBJECT shared;
0
+    OBJECT __ivars__; // slot
0
+    INTEGER num_bytes; // slot
0
+    INTEGER characters; // slot
0
+    OBJECT encoding; // slot
0
+    ByteArray* data; // slot
0
+    INTEGER hash; // slot
0
+    OBJECT shared; // slot
0
 
0
     static String* create(STATE, const char* str, size_t bytes = 0);
0
     static hashval hash_str(const unsigned char *bp, unsigned int sz);
0
@@ -30,11 +31,6 @@ namespace rubinius {
0
       return num_bytes->n2i();
0
     }
0
 
0
-    /* Allows the String object to be cast as a char* */
0
-    operator const char *() {
0
-      return (const char*)(data->bytes);
0
-    }
0
-
0
     /* TODO: since we're technically say it's ok to change this, we might
0
      * want to copy it first. */
0
     operator char *() {
0
@@ -55,6 +51,13 @@ namespace rubinius {
0
     String* add(STATE, String* other);
0
     String* add(STATE, char* other);
0
 
0
+    class Info : public TypeInfo {
0
+    public:
0
+      Info(object_type type) : TypeInfo(type) { }
0
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
0
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
0
+    };
0
+
0
   };
0
 };
0
 
...
20
21
22
23
 
24
25
26
 
27
28
29
...
20
21
22
 
23
24
25
 
26
27
28
29
0
@@ -20,10 +20,10 @@ namespace rubinius {
0
     if(!size) size = std::strlen(str);
0
 
0
     hashval hash = String::hash_str((unsigned char*)str, size);
0
-    OBJECT ent = strings->find_entry(state, hash);
0
+    Tuple* ent = strings->find_entry(state, hash);
0
 
0
     /* If it wasn't present, use the longer, more correct version. */
0
-    if(ent->nil_p() || ent == Qundef) {
0
+    if(!ent) {
0
       return lookup(state, String::create(state, str, size));
0
     }
0
 
...
15
16
17
18
19
20
21
 
22
23
24
...
28
29
30
 
 
 
 
31
32
33
 
 
 
34
35
36
...
208
209
210
211
 
212
213
 
214
215
216
...
15
16
17
 
 
 
 
18
19
20
21
...
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
...
212
213
214
 
215
216
 
217
218
219
220
0
@@ -15,10 +15,7 @@ namespace rubinius {
0
   }
0
 
0
   Task* Task::create(STATE, OBJECT recv, CompiledMethod* meth) {
0
-    Task* task = (Task*)state->new_struct(G(task), sizeof(Task));
0
-    task->ip = 0;
0
-    task->sp = -1;
0
-    task->state = state;
0
+    Task* task = create(state);
0
     task->make_active(task->generate_context(recv, meth));
0
     return task;
0
   }
0
@@ -28,9 +25,16 @@ namespace rubinius {
0
     task->ip = 0;
0
     task->sp = -1;
0
     task->state = state;
0
+    SET(task, control_channel, Qnil);
0
+    SET(task, debug_channel, Qnil);
0
+    SET(task, active, Qnil);
0
+
0
     return task;
0
   }
0
 
0
+  void Task::Info::mark(Task* obj) {
0
+  }
0
+
0
   MethodContext* Task::generate_context(OBJECT recv, CompiledMethod* meth) {
0
     MethodContext* ctx = MethodContext::create(state);
0
 
0
@@ -208,9 +212,9 @@ namespace rubinius {
0
       return (Executable*)Qnil;
0
     }
0
 
0
-    CompiledMethod::Visibility *vis;
0
+    MethodVisibility *vis;
0
 
0
-    vis = try_as<CompiledMethod::Visibility>(msg.method);
0
+    vis = try_as<MethodVisibility>(msg.method);
0
     if(vis) {
0
       return vis->method;
0
     }
...
89
90
91
 
92
93
94
95
96
97
...
89
90
91
92
93
94
 
95
96
97
0
@@ -89,9 +89,9 @@ namespace rubinius {
0
 
0
     class Info : public TypeInfo {
0
     public:
0
+      Info(object_type type) : TypeInfo(type) { }
0
       virtual void mark(Task* obj);
0
     };
0
-
0
   };
0
 }
0
 
...
20
21
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
...
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
0
@@ -20,4 +20,18 @@ namespace rubinius {
0
     SET(thr, priority, Object::i2n(2));
0
     return thr;
0
   }
0
+
0
+  void Thread::boot_task(STATE) {
0
+    Task* task = Task::create(state);
0
+    SET(this, task, task);
0
+  }
0
+
0
+  void Thread::set_top(STATE, OBJECT val) {
0
+    task->stack->put(state, task->sp, val);
0
+  }
0
+  
0
+  void Thread::sleep_for(STATE, Channel* chan) {
0
+    channel = chan;
0
+    set_ivar(state, state->symbol("@sleep"), Qtrue);
0
+  }
0
 }
...
7
8
9
 
10
11
12
13
14
15
 
16
 
17
18
19
...
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
0
@@ -7,13 +7,16 @@ namespace rubinius {
0
     const static size_t fields = 5;
0
     const static object_type type = ThreadType;
0
 
0
+    OBJECT ivars;
0
     Task* task;
0
     Channel* channel;
0
     FIXNUM priority;
0
 
0
     static void init(STATE);
0
     static Thread* create(STATE);
0
+    void boot_task(STATE);
0
     void sleep_for(STATE, Channel* chan);
0
+    void set_top(STATE, OBJECT val);
0
   };
0
 
0
   class DeadLock : public Assertion {
...
75
76
77
78
 
79
80
81
...
75
76
77
 
78
79
80
81
0
@@ -75,7 +75,7 @@ namespace rubinius {
0
       ev.data = this;
0
     }
0
 
0
-    void Read::into_buffer(rubinius::IO::Buffer *buf, size_t bytes) {
0
+    void Read::into_buffer(rubinius::IOBuffer *buf, size_t bytes) {
0
       count = bytes;
0
       buffer.set(buf);
0
     }
...
18
19
20
21
 
22
23
24
...
57
58
59
60
 
61
62
63
...
18
19
20
 
21
22
23
24
...
57
58
59
 
60
61
62
63
0
@@ -18,7 +18,7 @@ namespace rubinius {
0
       STATE;
0
       ObjectCallback* channel;
0
       size_t id;
0
-      TypedRoot<IO::Buffer*> buffer;
0
+      TypedRoot<IOBuffer*> buffer;
0
       Loop* loop;
0
 
0
       Event(STATE, ObjectCallback* chan);
0
@@ -57,7 +57,7 @@ namespace rubinius {
0
 
0
       Read(STATE, ObjectCallback* chan, int fd);
0
       virtual ~Read() { }
0
-      void into_buffer(rubinius::IO::Buffer* buffer, size_t bytes);
0
+      void into_buffer(rubinius::IOBuffer* buffer, size_t bytes);
0
       virtual bool activated();
0
     };
0
 
...
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
...
21
22
23
 
24
25
26
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
29
0
@@ -21,50 +21,9 @@
0
 #define RBX_FFI_TYPE_STRPTR  17
0
 #define RBX_FFI_TYPE_CHARARR 18
0
 
0
-#include <ffi.h>
0
 #include "prelude.hpp"
0
 #include "object.hpp"
0
 #include "message.hpp"
0
 
0
-namespace rubinius {
0
-  class MemoryPointer : public BuiltinType {
0
-    public:
0
-    const static size_t fields = 0;
0
-    const static object_type type = MemPtrType;
0
-
0
-    void* pointer;
0
-
0
-    static MemoryPointer* create(STATE, void* ptr);
0
-
0
-    OBJECT get_field(STATE, int offset, int type);
0
-    void   set_field(STATE, int offset, int type, OBJECT val);
0
-  };
0
-
0
-  class NativeFunction : public Executable {
0
-    public:
0
-    struct ffi_stub {
0
-      ffi_cif cif;
0
-      size_t arg_count;
0
-      int *arg_types;
0
-      int ret_type;
0
-      void *ep;
0
-    };
0
-
0
-    static const size_t fields = 7;
0
-    OBJECT name;
0
-    String* file;
0
-    MemoryPointer* data;
0
-
0
-    static void* find_symbol(STATE, OBJECT library, String* name);
0
-
0
-    static size_t type_size(size_t type);
0
-    static NativeFunction* create(STATE, OBJECT name, int args);
0
-    void bind(STATE, int arg_count, int *arg_types, int ret_type, void* func);
0
-    static NativeFunction* bind(STATE, String* library, String* name, Array* args, OBJECT ret);
0
-    void **marshal_arguments(STATE, Message *msg);
0
-    OBJECT call(STATE, Message* msg);
0
-  };
0
-
0
-}
0
 
0
 #endif
...
49
50
51
52
53
54
 
 
 
55
56
57
...
49
50
51
 
 
 
52
53
54
55
56
57
0
@@ -49,9 +49,9 @@ namespace rubinius {
0
       entry->name = name;
0
       entry->module = mod;
0
 
0
-      if(kind_of<CompiledMethod::Visibility>(meth)) {
0
-        CompiledMethod::Visibility* vis;
0
-        vis = as<CompiledMethod::Visibility>(meth);
0
+      if(kind_of<MethodVisibility>(meth)) {
0
+        MethodVisibility* vis;
0
+        vis = as<MethodVisibility>(meth);
0
 
0
         if(vis->public_p(state)) {
0
           entry->is_public = true;
...
55
56
57
 
58
59
60
...
99
100
101
102
 
 
103
104
105
...
55
56
57
58
59
60
61
...
100
101
102
 
103
104
105
106
107
0
@@ -55,6 +55,7 @@ namespace rubinius {
0
     TypedRoot<Module*> vm;
0
     TypedRoot<Thread*> current_thread;
0
     TypedRoot<Task*> current_task;
0
+    TypedRoot<OBJECT> main;
0
 
0
     /* Leave this as the last data member always */
0
     TypedRoot<Class*> special_classes[SPECIAL_CLASS_SIZE];
0
@@ -99,7 +100,8 @@ namespace rubinius {
0
       top_scope(&roots), on_gc_channel(&roots),
0
       vm(&roots),
0
       current_thread(&roots),
0
-      current_task(&roots)
0
+      current_task(&roots),
0
+      main(&roots)
0
     { }
0
   };
0
 };
...
72
73
74
75
 
76
77
78
...
80
81
82
83
 
84
85
86
...
197
198
199
200
 
201
202
203
...
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
...
953
954
955
956
 
957
958
959
...
965
966
967
 
 
 
 
 
 
 
 
 
 
968
969
970
971
 
972
973
974
...
2359
2360
2361
2362
 
2363
2364
2365
...
2451
2452
2453
2454
 
2455
2456
2457
...
2521
2522
2523
2524
 
2525
2526
2527
...
2612
2613
2614
2615
 
2616
2617
2618
...
2687
2688
2689
2690
 
2691
2692
2693
...
2780
2781
2782
2783
 
2784
2785
2786
...
3340
3341
3342
3343
3344
 
3345
3346
 
3347
3348
3349
3350
 
3351
3352
 
3353
3354
3355
...
72
73
74
 
75
76
77
78
...
80
81
82
 
83
84
85
86
...
197
198
199
 
200
201
202
203
...
852
853
854
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
855
856
857
...
871
872
873
 
874
875
876
877
...
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
 
899
900
901
902
...
2287
2288
2289
 
2290
2291
2292
2293
...
2379
2380
2381
 
2382
2383
2384
2385
...
2449
2450
2451
 
2452
2453
2454
2455
...
2540
2541
2542
 
2543
2544
2545
2546
...
2615
2616
2617
 
2618
2619
2620
2621
...
2708
2709
2710
 
2711
2712
2713
2714
...
3268
3269
3270
 
 
3271
3272
 
3273
3274
3275
3276
 
3277
3278
 
3279
3280
3281
3282
0
@@ -72,7 +72,7 @@ class TestInstructions : public CxxTest::TestSuite {
0
         fd.puts "void #{meth}() {"
0
         fd.puts "Task* task = Task::create(state);"
0
         fd.puts "CompiledMethod* cm = CompiledMethod::create(state);"
0
-        fd.puts "cm->iseq = ISeq::create(state, 10);"
0
+        fd.puts "cm->iseq = InstructionSequence::create(state, 10);"
0
         fd.puts "cm->stack_size = Object::i2n(10);"
0
         fd.puts "MethodContext* ctx = task->generate_context(Qnil, cm);"
0
         fd.puts "task->make_active(ctx);"
0
@@ -80,7 +80,7 @@ class TestInstructions : public CxxTest::TestSuite {
0
         fd.puts "Tuple* stack = task->stack; stack += 0;"
0
         fd.puts "task->literals = Tuple::create(state, 10);"
0
         fd.puts "opcode stream[100];"
0
-        fd.puts "stream[0] = ISeq::insn_#{ins.opcode};"
0
+        fd.puts "stream[0] = InstructionSequence::insn_#{ins.opcode};"
0
         fd.puts "#define run(val) task->execute_stream(stream)"
0
         fd.puts "#line #{line} \"instructions.rb\""
0
         fd.puts code
0
@@ -197,7 +197,7 @@ class TestInstructions : public CxxTest::TestSuite {
0
   end
0
 
0
   def generate_names
0
-    str =  "const char *rubinius::ISeq::get_instruction_name(int op) {\n"
0
+    str =  "const char *rubinius::InstructionSequence::get_instruction_name(int op) {\n"
0
     str << "static const char instruction_names[] = {\n"
0
     InstructionSet::OpCodes.each do |ins|
0
       str << "  \"#{ins.opcode.to_s}\\0\"\n"
0
@@ -852,88 +852,6 @@ CODE
0
   end
0
 
0
   # [Operation]
0
-  #   Store a value into the specified object field
0
-  # [Format]
0
-  #   \store_field
0
-  # [Stack Before]
0
-  #   * field
0
-  #   * value
0
-  #   * object
0
-  #   * ...
0
-  # [Stack After]
0
-  #   * object
0
-  #   * ...
0
-  # [Description]
0
-  #   Overwrite the value of a particular field slot with the specified
0
-  #   object. The object reference is left on the stack.
0
-
0
-  def store_field
0
-    <<-CODE
0
-    t1 = stack_pop();
0
-    t2 = stack_pop();
0
-    t3 = stack_pop();
0
-    size_t idx = (size_t)as<Fixnum>(t1)->n2i();
0
-    check_bounds(t3, idx);
0
-    SET(t3, field[idx], t2);
0
-    stack_push(t3);
0
-    CODE
0
-  end
0
-
0
-  def test_store_field
0
-    <<-CODE
0
-    Tuple* tup = Tuple::create(state, 3);
0
-    tup->put(state, 0, Qnil);
0
-
0
-    stack->put(state, ++task->sp, tup);
0
-    stack->put(state, ++task->sp, Qtrue);
0
-    stack->put(state, ++task->sp, Object::i2n(0));
0
-
0
-    run();
0
-
0
-    TS_ASSERT_EQUALS(tup->at(0), Qtrue);
0
-    CODE
0
-  end
0
-
0
-  # [Operation]
0
-  #   Retrieve the value within the field of the specified object
0
-  # [Format]
0
-  #   \fetch_field
0
-  # [Stack Before]
0
-  #   * field
0
-  #   * object
0
-  #   * ...
0
-  # [Stack After]
0
-  #   * value
0
-  #   * ...
0
-  # [Description]
0
-  #   Retrieve the object of the specified object field number.
0
-
0
-  def fetch_field
0
-    <<-CODE
0
-    t1 = stack_pop();
0
-    t2 = stack_pop();
0
-    size_t index = as<Fixnum>(t1)->n2i();
0
-    check_bounds(t2, index);
0
-    stack_push(t2->at(index));
0
-    CODE
0
-  end
0
-
0
-  def test_fetch_field
0
-    <<-CODE
0
-    Tuple* tup = Tuple::create(state, 3);
0
-    tup->put(state, 0, Qtrue);
0
-
0
-    stack->put(state, ++task->sp, tup);
0
-    stack->put(state, ++task->sp, Object::i2n(0));
0
-
0
-    run();
0
-
0
-    TS_ASSERT_EQUALS(task->sp, 0);
0
-    TS_ASSERT_EQUALS(stack->at(task->sp), Qtrue);
0
-    CODE
0
-  end
0
-
0
-  # [Operation]
0
   #   Pushes a value from an object field onto the stack
0
   # [Format]
0
   #   \push_my_field fld
0
@@ -953,7 +871,7 @@ CODE
0
   def push_my_field
0
     <<-CODE
0
     next_int;
0
-    stack_push(self->at(_int));
0
+    stack_push(self->get_field(state, _int));
0
     CODE
0
   end
0
 
0
@@ -965,10 +883,20 @@ CODE
0
     task->self = tup;
0
 
0
     stream[1] = (opcode)0;
0
+
0
+    TS_ASSERT_THROWS(run(), std::runtime_error);
0
+
0
+    Class* cls = state->new_class("Blah");
0
+
0
+    task->self = cls;
0
+
0
+    stream[1] = (opcode)2;
0
+
0
+    task->sp = -1;
0
     run();
0
 
0
     TS_ASSERT_EQUALS(task->sp, 0);
0
-    TS_ASSERT_EQUALS(stack->at(task->sp), Qtrue);
0
+    TS_ASSERT_EQUALS(stack->at(task->sp), state->symbol("Blah"));
0
     CODE
0
   end
0
 
0
@@ -2359,7 +2287,7 @@ CODE
0
   def test_send_method
0
     <<-CODE
0
     CompiledMethod* target = CompiledMethod::create(state);
0
-    target->iseq = ISeq::create(state, 0);
0
+    target->iseq = InstructionSequence::create(state, 0);
0
     target->total_args = Object::i2n(0);
0
     target->required_args = target->total_args;
0
     target->stack_size = Object::i2n(10);
0
@@ -2451,7 +2379,7 @@ CODE
0
   def test_send_stack
0
     <<-CODE
0
     CompiledMethod* target = CompiledMethod::create(state);
0
-    target->iseq = ISeq::create(state, 0);
0
+    target->iseq = InstructionSequence::create(state, 0);
0
     target->total_args = Object::i2n(1);
0
     target->required_args = target->total_args;
0
     target->stack_size = Object::i2n(1);
0
@@ -2521,7 +2449,7 @@ CODE
0
   def test_send_stack_with_block
0
     <<-CODE
0
     CompiledMethod* target = CompiledMethod::create(state);
0
-    target->iseq = ISeq::create(state, 0);
0
+    target->iseq = InstructionSequence::create(state, 0);
0
     target->total_args = Object::i2n(1);
0
     target->required_args = target->total_args;
0
     target->stack_size = Object::i2n(1);
0
@@ -2612,7 +2540,7 @@ CODE
0
   def test_send_stack_with_splat
0
     <<-CODE
0
     CompiledMethod* target = CompiledMethod::create(state);
0
-    target->iseq = ISeq::create(state, 0);
0
+    target->iseq = InstructionSequence::create(state, 0);
0
     target->total_args = Object::i2n(2);
0
     target->required_args = target->total_args;
0
     target->stack_size = Object::i2n(2);
0
@@ -2687,7 +2615,7 @@ CODE
0
   def test_send_super_stack_with_block
0
     <<-CODE
0
     CompiledMethod* target = CompiledMethod::create(state);
0
-    target->iseq = ISeq::create(state, 0);
0
+    target->iseq = InstructionSequence::create(state, 0);
0
     target->total_args = Object::i2n(1);
0
     target->required_args = target->total_args;
0
     target->stack_size = Object::i2n(1);
0
@@ -2780,7 +2708,7 @@ CODE
0
   def test_send_super_stack_with_splat
0
     <<-CODE
0
     CompiledMethod* target = CompiledMethod::create(state);
0
-    target->iseq = ISeq::create(state, 0);
0
+    target->iseq = InstructionSequence::create(state, 0);
0
     target->total_args = Object::i2n(2);
0
     target->required_args = target->total_args;
0
     target->stack_size = Object::i2n(2);
0
@@ -3340,16 +3268,15 @@ perform_no_ss_send:
0
 
0
   def shift_tuple
0
     <<-CODE
0
-    t1 = stack_pop();
0
-    sassert(t1->reference_p());
0
+    Tuple* tup = as<Tuple>(stack_pop());
0
     if(NUM_FIELDS(t1) == 0) {
0
-      stack_push(t1);
0
+      stack_push(tup);
0
       stack_push(Qnil);
0
     } else {
0
       j = NUM_FIELDS(t1) - 1;
0
-      t3 = t1->at(0);
0
+      t3 = tup->at(0);
0
       Tuple* tup = Tuple::create(state, j);
0
-      tup->copy_from(state, as<Tuple>(t1), 1, j);
0
+      tup->copy_from(state, tup, 1, j);
0
       stack_push(t2);
0
       stack_push(t3);
0
     }
...
36
37
38
39
 
 
 
40
41
42
43
44
45
46
 
 
47
48
49
50
 
51
52
 
 
 
 
53
54
55
56
57
58
59
 
 
60
61
62
63
64
 
 
 
 
 
 
65
66
67
...
123
124
125
126
127
128
 
 
 
 
 
 
129
130
131
132
133
 
 
 
 
134
135
136
 
 
 
 
 
 
 
137
138
139
...
141
142
143
144
145
146
147
148
 
149
150
151
...
154
155
156
157
158
159
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
161
162
...
165
166
167
 
168
169
170
...
220
221
222
223
224
 
 
225
226
227
...
36
37
38
 
39
40
41
42
43
44
45
46
47
 
48
49
50
51
52
53
54
55
 
56
57
58
59
60
61
62
63
64
65
 
66
67
68
69
70
71
 
72
73
74
75
76
77
78
79
80
...
136
137
138
 
 
 
139
140
141
142
143
144
145
146
 
 
 
147
148
149
150
151
 
 
152
153
154
155
156
157
158
159
160
161
...
163
164
165
 
 
 
 
 
166
167
168
169
...
172
173
174
 
 
 
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
...
194
195
196
197
198
199
200
...
250
251
252
 
 
253
254
255
256
257
0
@@ -36,32 +36,45 @@ namespace rubinius {
0
     stream >> count;
0
     String* str = String::create(state, NULL, count + 1);
0
 
0
-    stream >> (char*)*str;
0
+    stream.get(); // read off newline
0
+    stream.read((char*)*str, count);
0
+    stream.get(); // read off newline
0
 
0
     return str;
0
   }
0
 
0
   void Marshaller::set_symbol(SYMBOL sym) {
0
     String* str = sym->to_str(state);
0
-    stream << "x" << endl << (char*)*str << endl;
0
+    stream << "x" << endl << str->size() << endl;
0
+    stream.write((char*)*str, str->size()) << endl;
0
   }
0
 
0
   SYMBOL UnMarshaller::get_symbol() {
0
     char data[1024];
0
+    size_t count;
0
 
0
-    stream >> data;
0
+    stream >> count;
0
+    stream.get();
0
+    stream.read(data, count + 1);
0
+    data[count] = 0; // clamp
0
 
0
     return G(symbols)->lookup(state, data);
0
   }
0
 
0
   void Marshaller::set_sendsite(SendSite* ss) {
0
     String* str = ss->name->to_str(state);
0
-    stream << "S" << endl << (char*)*str << endl;
0
+    stream << "S" << endl << str->size() << endl;
0
+    stream.write((char*)*str, str->size()) << endl;
0
   }
0
 
0
   SendSite* UnMarshaller::get_sendsite() {
0
     char data[1024];
0
-    stream >> data;
0
+    size_t count;
0
+
0
+    stream >> count;
0
+    stream.get();
0
+    stream.read(data, count + 1);
0
+    data[count] = 0; // clamp
0
 
0
     SYMBOL sym = G(symbols)->lookup(state, data);
0
 
0
@@ -123,17 +136,26 @@ namespace rubinius {
0
     return Float::create(state, val);
0
   }
0
 
0
-  void Marshaller::set_iseq(ISeq* iseq) {
0
-    stream << "i" << endl << iseq->body_in_bytes() << endl;
0
-    stream.write(iseq->bytes, iseq->body_in_bytes()) << endl;
0
+  void Marshaller::set_iseq(InstructionSequence* iseq) {
0
+    Tuple* ops = iseq->opcodes;
0
+    stream << "i" << endl << ops->field_count << endl;
0
+    for(size_t i = 0; i < ops->field_count; i++) {
0
+      stream << as<Fixnum>(ops->at(i))->to_nint() << endl;
0
+    }
0
   }
0
 
0
-  ISeq* UnMarshaller::get_iseq() {
0
-    size_t bytes;
0
-    stream >> bytes;
0
+  InstructionSequence* UnMarshaller::get_iseq() {
0
+    size_t count;
0
+    long op;
0
+    stream >> count;
0
 
0
-    ISeq* iseq = ISeq::create(state, bytes);
0
-    stream.read(iseq->bytes, bytes);
0
+    InstructionSequence* iseq = InstructionSequence::create(state, count);
0
+    Tuple* ops = iseq->opcodes;
0
+
0
+    for(size_t i = 0; i < count; i++) {
0
+      stream >> op;
0
+      ops->put(state, i, Object::i2n(op));
0
+    }
0
 
0
     iseq->post_marshal(state);
0
 
0
@@ -141,11 +163,7 @@ namespace rubinius {
0
   }
0
 
0
   void Marshaller::set_cmethod(CompiledMethod* cm) {
0
-    stream << "M" << endl << 1 << endl;
0
-
0
-    for(size_t i = 0; i < CompiledMethod::saved_fields; i++) {
0
-      marshal(cm->at(i));
0
-    }
0
+    assert(0);
0
   }
0
 
0
   CompiledMethod* UnMarshaller::get_cmethod() {
0
@@ -154,9 +172,20 @@ namespace rubinius {
0
 
0
     CompiledMethod* cm = CompiledMethod::create(state);
0
 
0
-    for(size_t i = 0; i < CompiledMethod::saved_fields; i++) {
0
-      SET(cm, field[i], unmarshal());
0
-    }
0
+    SET(cm, __ivars__, unmarshal());
0
+    SET(cm, primitive, unmarshal());
0
+    SET(cm, name,      unmarshal());
0
+    SET(cm, iseq,      unmarshal());
0
+    SET(cm, stack_size, unmarshal());
0
+    SET(cm, local_count, unmarshal());
0
+    SET(cm, required_args, unmarshal());
0
+    SET(cm, total_args, unmarshal());
0
+    SET(cm, splat,     unmarshal());
0
+    SET(cm, literals,  unmarshal());
0
+    SET(cm, exceptions, unmarshal());
0
+    SET(cm, lines,     unmarshal());
0
+    SET(cm, file,      unmarshal());
0
+    SET(cm, local_names, unmarshal());
0
 
0
     cm->post_marshal(state);
0
 
0
@@ -165,6 +194,7 @@ namespace rubinius {
0
 
0
   OBJECT UnMarshaller::unmarshal() {
0
     char code;
0
+    
0
     stream >> code;
0
 
0
     switch(code) {
0
@@ -220,8 +250,8 @@ namespace rubinius {
0
       set_tuple(as<Tuple>(obj));
0
     } else if(kind_of<Float>(obj)) {
0
       set_float(as<Float>(obj));
0
-    } else if(kind_of<ISeq>(obj)) {
0
-      set_iseq(as<ISeq>(obj));
0
+    } else if(kind_of<InstructionSequence>(obj)) {
0
+      set_iseq(as<InstructionSequence>(obj));
0
     } else if(kind_of<CompiledMethod>(obj)) {
0
       set_cmethod(as<CompiledMethod>(obj));
0
     } else {
...
30
31
32
33
 
34
35
36
...
52
53
54
55
 
56
57
58
...
30
31
32
 
33
34
35
36
...
52
53
54
 
55
56
57
58
0
@@ -30,7 +30,7 @@ namespace rubinius {
0
     void set_tuple(Tuple* o);
0
     void set_bignum(Bignum* o);
0
     void set_float(Float* o);
0
-    void set_iseq(ISeq* o);
0
+    void set_iseq(InstructionSequence* o);
0
     void set_cmethod(CompiledMethod* o);
0
   };
0
 
0
@@ -52,7 +52,7 @@ namespace rubinius {
0
     Tuple* get_tuple();
0
 
0
     Float* get_float();
0
-    ISeq* get_iseq();
0
+    InstructionSequence* get_iseq();
0
     CompiledMethod* get_cmethod();
0
   };
0
 }
...
76
77
78
 
79
80
81
...
91
92
93
94
 
 
 
 
 
 
 
95
96
97
...
108
109
110
111
112
113
114
...
132
133
134
 
 
135
136
137
...
295
296
297
298
299
300
301
302
303
304
305
306
307
...
352
353
354
 
 
355
356
357
...
365
366
367
 
 
 
 
368
369
370
...
374
375
376
377
 
378
379
380
381
382
383
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
384
385
386
387
388
389
390
 
391
392
393
394
395
396
 
 
 
397
398
399
400
 
401
402
403
...
76
77
78
79
80
81
82
...
92
93
94
 
95
96
97
98
99
100
101
102
103
104
...
115
116
117
 
118
119
120
...
138
139
140
141
142
143
144
145
...
303
304
305
 
 
 
 
 
 
 
306
307
308
...
353
354
355
356
357
358
359
360
...
368
369
370
371
372
373
374
375
376
377
...
381
382
383
 
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
 
420
421
422
423
424
425
426
427
428
429
430
431
432
 
433
434
435
436
0
@@ -76,6 +76,7 @@ to be a simple test for that bit pattern.
0
 #define REFERENCE_P(v) (TAG(v) == TAG_REF)
0
 
0
 #define INDEXED(obj) (REFERENCE_P(obj) && !obj->StoresBytes)
0
+#define STORE_BYTES(obj) (REFERENCE_P(obj) && obj->StoresBytes)
0
 
0
 #define SIZE_OF_OBJECT ((size_t)(sizeof(OBJECT)))
0
 
0
@@ -91,7 +92,13 @@ to be a simple test for that bit pattern.
0
   /* rubinius_object types, takes up 3 bits */
0
   typedef enum
0
   {
0
-    ObjectType      = 0,
0
+    InvalidType     = 0,
0
+    NumericType     ,
0
+    IntegerType     ,
0
+    FalseType       ,
0
+    TrueType        ,
0
+    NilType         ,
0
+    ObjectType      ,
0
     MContextType    ,
0
     BContextType    ,
0
     ClassType       ,
0
@@ -108,7 +115,6 @@ to be a simple test for that bit pattern.
0
     SymbolType      ,
0
     CMethodType     ,
0
     NMethodType     ,
0
-    NilType         ,
0
     BlockEnvType    ,
0
     TupleType       ,
0
     ArrayType       ,
0
@@ -132,6 +138,8 @@ to be a simple test for that bit pattern.
0
     ExecutableType  ,
0
     CMVisibilityType,
0
     ListType        ,
0
+    ListNodeType    ,
0
+    NativeFuncType  ,
0
 
0
     LastObjectType   // must remain at end
0
   } object_type;
0
@@ -295,13 +303,6 @@ to be a simple test for that bit pattern.
0
       return zone == MatureObjectZone;
0
     }
0
 
0
-    OBJECT at(size_t index) {
0
-      if(field_count <= index) {
0
-        throw new ObjectBoundsExceeded(this, index);
0
-      }
0
-      return field[index];
0
-    }
0
-
0
     bool forwarded_p() {
0
       return Forwarded == 1;
0
     }
0
@@ -352,6 +353,8 @@ to be a simple test for that bit pattern.
0
       return reference_p() && obj_type == type;
0
     }
0
 
0
+    OBJECT get_field(STATE, size_t index);
0
+    void   set_field(STATE, size_t index, OBJECT val);
0
     void cleanup(STATE);
0
 
0
     bool kind_of_p(STATE, OBJECT cls);
0
@@ -365,6 +368,10 @@ to be a simple test for that bit pattern.
0
     OBJECT get_ivar(STATE, OBJECT sym);
0
     OBJECT set_ivar(STATE, OBJECT sym, OBJECT val);
0
 
0
+    void copy_flags(STATE, OBJECT other);
0
+    void copy_ivars(STATE, OBJECT other);
0
+    void copy_metaclass(STATE, OBJECT other);
0
+
0
     static const char* type_to_name(object_type type);
0
   };
0
 
0
@@ -374,30 +381,56 @@ to be a simple test for that bit pattern.
0
 
0
   /* Given builtin-class +T+, return true if +obj+ is of class +T+ */
0
   template <class T>
0
-    static bool kind_of(OBJECT obj) {
0
+    static inline bool kind_of(OBJECT obj) {
0
       if(obj->reference_p()) {
0
         return obj->obj_type == T::type;
0
       }
0
       return false;
0
     }
0
 
0
+  /* Another version of kind_of that shouldn't be specialized for subtype
0
+   * compatibility. */
0
+  template <class T>
0
+    static inline bool instance_of(OBJECT obj) {
0
+      if(obj->reference_p()) {
0
+        return obj->obj_type == T::type;
0
+      }
0
+      return false;
0
+    }
0
+
0
+  template <>
0
+    static inline bool kind_of<Object>(OBJECT obj) {
0
+      return true;
0
+    }
0
+
0
+  template <>
0
+    static inline bool kind_of<Class>(OBJECT obj) {
0
+      return obj->obj_type == ClassType || 
0
+        obj->obj_type == MetaclassType ||
0
+        obj->obj_type == IncModType;
0
+    }
0
+
0
+
0
   /* Used when casting between object typ