<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>vm/.gitignore</filename>
    </added>
    <added>
      <filename>vm/builtin_block_environment.hpp</filename>
    </added>
    <added>
      <filename>vm/builtin_bytearray.hpp</filename>
    </added>
    <added>
      <filename>vm/builtin_compiledmethod.hpp</filename>
    </added>
    <added>
      <filename>vm/builtin_exception.hpp</filename>
    </added>
    <added>
      <filename>vm/builtin_executable.hpp</filename>
    </added>
    <added>
      <filename>vm/builtin_fixnum.hpp</filename>
    </added>
    <added>
      <filename>vm/builtin_immediates.hpp</filename>
    </added>
    <added>
      <filename>vm/builtin_io.hpp</filename>
    </added>
    <added>
      <filename>vm/builtin_lookuptable.hpp</filename>
    </added>
    <added>
      <filename>vm/builtin_memorypointer.hpp</filename>
    </added>
    <added>
      <filename>vm/builtin_methodtable.hpp</filename>
    </added>
    <added>
      <filename>vm/builtin_nativefunction.hpp</filename>
    </added>
    <added>
      <filename>vm/builtin_staticscope.hpp</filename>
    </added>
    <added>
      <filename>vm/builtin_symbol.hpp</filename>
    </added>
    <added>
      <filename>vm/builtin_tuple.hpp</filename>
    </added>
    <added>
      <filename>vm/compiled_file.cpp</filename>
    </added>
    <added>
      <filename>vm/compiled_file.hpp</filename>
    </added>
    <added>
      <filename>vm/doc/execution.txt</filename>
    </added>
    <added>
      <filename>vm/environment.cpp</filename>
    </added>
    <added>
      <filename>vm/environment.hpp</filename>
    </added>
    <added>
      <filename>vm/field_extract.rb</filename>
    </added>
    <added>
      <filename>vm/main.cpp</filename>
    </added>
    <added>
      <filename>vm/primitives.cpp</filename>
    </added>
    <added>
      <filename>vm/primitives.hpp</filename>
    </added>
    <added>
      <filename>vm/test/test_compiled_file.hpp</filename>
    </added>
    <added>
      <filename>vm/test/test_compiledmethod.hpp</filename>
    </added>
    <added>
      <filename>vm/test/test_instructions.hpp</filename>
    </added>
    <added>
      <filename>vm/test/test_vmmethod.hpp</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -4,13 +4,14 @@
 namespace rubinius {
   class Array : public BuiltinType {
     public:
-    const static size_t fields = 4;
+    const static size_t fields = 5;
     const static object_type type = ArrayType;
 
-    INTEGER total;
-    Tuple* tuple;
-    INTEGER start;
-    OBJECT shared;
+    OBJECT __ivars__; // slot
+    INTEGER total; // slot
+    Tuple* tuple; // slot
+    INTEGER start; // slot
+    OBJECT shared; // slot
 
     size_t size() {
       return total-&gt;n2i();
@@ -23,6 +24,13 @@ namespace rubinius {
     OBJECT set(STATE, size_t idx, OBJECT val);
     OBJECT append(STATE, OBJECT val);
     bool   includes_p(STATE, OBJECT val);
+
+    class Info : public TypeInfo {
+    public:
+      Info(object_type type) : TypeInfo(type) { }
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
+    };
   };
 };
 </diff>
      <filename>vm/builtin_array.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -170,7 +170,7 @@ namespace rubinius {
   }
 
   void Bignum::init(STATE) {
-    state-&gt;add_type_info(new Bignum::Info(G(bignum)));
+    state-&gt;add_type_info(new Bignum::Info(Bignum::type));
   }
 
   Bignum* Bignum::create(STATE, native_int num) {
@@ -253,7 +253,6 @@ namespace rubinius {
 
   INTEGER Bignum::div(STATE, INTEGER b, INTEGER mod_obj) {
     NMP;
-    mp_int *mod = MP(mod_obj);
     mp_int m, x, y, z;
 
     if(kind_of&lt;Fixnum&gt;(b)) {
@@ -297,7 +296,8 @@ namespace rubinius {
       mp_copy(&amp;y, &amp;m);
     }
 
-    if(mod) {
+    if(!mod_obj-&gt;nil_p()) {
+      mp_int *mod = MP(mod_obj);
       mp_copy(&amp;m, mod);
     }
 </diff>
      <filename>vm/builtin_bignum.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -57,7 +57,7 @@ namespace rubinius {
 
     class Info : public TypeInfo {
     public:
-      Info(Class* cls) : TypeInfo(cls) { }
+      Info(object_type type) : TypeInfo(type) { }
       virtual void cleanup(OBJECT obj);
     };
   };</diff>
      <filename>vm/builtin_bignum.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -9,6 +9,13 @@ namespace rubinius {
   }
 
   void Channel::send(STATE, OBJECT val) {
+    if(!waiting-&gt;empty_p()) {
+      Thread* thr = as&lt;Thread&gt;(waiting-&gt;shift(state));
+      thr-&gt;set_top(state, val);
+      state-&gt;queue_thread(thr);
+      return;
+    }
+
     if(value-&gt;nil_p()) {
       List* lst = List::create(state);
       lst-&gt;append(state, val);
@@ -33,10 +40,7 @@ namespace rubinius {
   }
 
   bool Channel::has_readers_p() {
-    return false;
+    return !waiting-&gt;empty_p();
   }
 
-  void Thread::sleep_for(STATE, Channel* chan) {
-
-  }
 }</diff>
      <filename>vm/builtin_channel.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -7,16 +7,25 @@ namespace rubinius {
     const static size_t fields = 3;
     const static object_type type = ChannelType;
 
-    OBJECT value;
-    List* waiting;
+    OBJECT __ivars__; // slot
+    OBJECT value; // slot
+    List* waiting; // slot
 
     static Channel* create(STATE);
     void send(STATE, OBJECT);
     void receive(STATE);
     bool has_readers_p();
+
+    class Info : public TypeInfo {
+    public:
+      Info(object_type type) : TypeInfo(type) { }
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
+    };
   };
 
   class ChannelCallback : public ObjectCallback {
+  public:
     TypedRoot&lt;Channel*&gt; channel;
 
     ChannelCallback(STATE, Channel* chan) : ObjectCallback(state) {</diff>
      <filename>vm/builtin_channel.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -78,14 +78,13 @@ namespace rubinius {
   MetaClass* MetaClass::attach(STATE, OBJECT obj, OBJECT sup) {
     MetaClass *meta;
 
-    meta = (MetaClass*)state-&gt;om-&gt;new_object(G(metaclass),
-                                             MetaClass::fields);
+    meta = (MetaClass*)state-&gt;new_object(G(metaclass));
     if(!sup) { sup = obj-&gt;klass; }
     meta-&gt;IsMeta = TRUE;
     SET(meta, attached_instance, obj);
     meta-&gt;setup(state);
     SET(meta, superclass, sup);
-    state-&gt;om-&gt;set_class(obj, meta);
+    SET(obj, klass, meta);
 
     return meta;
   }</diff>
      <filename>vm/builtin_class.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -6,16 +6,14 @@
 namespace rubinius {
   class Module : public BuiltinType {
     public:
-    const static size_t fields = 7;
+    const static size_t fields = 5;
     const static object_type type = ModuleType;
 
-    OBJECT instance_variables;
-    LookupTable* method_table;
-    OBJECT method_cache;
-    SYMBOL name;
-    LookupTable* constants;
-    OBJECT encloser;
-    Class* superclass;
+    OBJECT __ivars__; // slot
+    LookupTable* method_table; // slot
+    SYMBOL name; // slot
+    LookupTable* constants; // slot
+    Module* superclass; // slot
 
     static Module* create(STATE);
     void setup(STATE);
@@ -28,23 +26,37 @@ namespace rubinius {
     OBJECT get_const(STATE, char* sym);
 
     void set_name(STATE, Module* under, SYMBOL name);
+
+    class Info : public TypeInfo {
+    public:
+      Info(object_type type) : TypeInfo(type) { }
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
+    };
   };
 
   class Class : public Module {
     public:
-    const static size_t fields = 11;
+    const static size_t fields = 9;
     const static object_type type = ClassType;
 
-    FIXNUM instance_fields;
-    OBJECT has_ivars;
-    OBJECT needs_cleanup;
-    FIXNUM instance_type;
+    FIXNUM instance_fields; // slot
+    OBJECT has_ivars; // slot
+    OBJECT needs_cleanup; // slot
+    FIXNUM instance_type; // slot
 
     void set_object_type(size_t type) {
       instance_type = Object::i2n(type);
     }
 
     static Class* create(STATE, Class* super);
+
+    class Info : public TypeInfo {
+    public:
+      Info(object_type type) : TypeInfo(type) { }
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
+    };
   };
 
   /* See t1 */
@@ -57,22 +69,34 @@ namespace rubinius {
 
   class MetaClass : public Class {
     public:
-    const static size_t fields = 12;
+    const static size_t fields = 10;
     const static object_type type = MetaclassType;
 
-    OBJECT attached_instance;
-
-    static bool is_a(OBJECT obj) {
-      return obj-&gt;obj_type == MetaclassType;
-    }
+    OBJECT attached_instance; // slot
 
     static MetaClass* attach(STATE, OBJECT obj, OBJECT sup = NULL);
+
+    class Info : public TypeInfo {
+    public:
+      Info(object_type type) : TypeInfo(type) { }
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
+    };
   };
 
   class IncludedModule : public Module {
     public:
+    const static size_t field = 6;
+    const static object_type type = IncModType;
 
-    OBJECT module;
+    OBJECT module; // slot
+
+    class Info : public TypeInfo {
+    public:
+      Info(object_type type) : TypeInfo(type) { }
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
+    };
   };
 
 };</diff>
      <filename>vm/builtin_class.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,6 @@
 #include &quot;builtin.hpp&quot;
 #include &quot;ffi.hpp&quot;
+#include &quot;marshal.hpp&quot;
 
 namespace rubinius {
   CompiledMethod* CompiledMethod::create(STATE) {
@@ -7,8 +8,8 @@ namespace rubinius {
     return cm;
   }
 
-  CompiledMethod::Visibility* CompiledMethod::Visibility::create(STATE) {
-    return (CompiledMethod::Visibility*)state-&gt;new_object(G(cmethod_vis));
+  MethodVisibility* MethodVisibility::create(STATE) {
+    return (MethodVisibility*)state-&gt;new_object(G(cmethod_vis));
   }
 
   void CompiledMethod::post_marshal(STATE) {</diff>
      <filename>vm/builtin_compiledmethod.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -13,6 +13,9 @@ namespace rubinius {
 
   }
 
+  void MethodContext::Info::mark(MethodContext* obj) {
+  }
+
   BlockContext* BlockContext::create(STATE) {
     return (BlockContext*)state-&gt;new_struct(G(blokctx), sizeof(BlockContext));
   }
@@ -21,13 +24,17 @@ namespace rubinius {
 
   }
 
+  void BlockEnvironment::call(STATE, Message&amp; msg) {
+
+  }
+
   BlockContext* BlockEnvironment::create_context(STATE) {
     BlockContext* ctx = BlockContext::create(state);
     SET(ctx, sender, (MethodContext*)Qnil);
     SET(ctx, name, (SYMBOL)this);
     SET(ctx, cm, method);
     SET(ctx, stack, Tuple::create(state, method-&gt;stack_size-&gt;to_nint()));
-    
+
     ctx-&gt;vmm = method-&gt;vmmethod(state);
     ctx-&gt;ip = 0;
     ctx-&gt;sp = method-&gt;number_of_locals() - 1;
@@ -37,9 +44,9 @@ namespace rubinius {
 
   BlockEnvironment* BlockEnvironment::under_context(STATE, CompiledMethod* cm,
       MethodContext* parent, MethodContext* active) {
-    
+
     BlockEnvironment* be = (BlockEnvironment*)state-&gt;new_object(G(blokenv));
-    
+
     parent-&gt;reference(state);
     active-&gt;reference(state);
 </diff>
      <filename>vm/builtin_contexts.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -27,7 +27,7 @@ namespace rubinius {
     int    sp;
     size_t args;
     OBJECT block;
-    SYMBOL name;
+    OBJECT name;
     bool   no_value;
 
     /* Locals are stored at the top of the stack. */
@@ -37,6 +37,8 @@ namespace rubinius {
     void reference(STATE);
 
     class Info : public TypeInfo {
+    public:
+      Info(object_type type) : TypeInfo(type) { }
       virtual void mark(MethodContext* obj);
     };
   };
@@ -52,9 +54,18 @@ namespace rubinius {
 
     static BlockContext* create(STATE);
 
-    class Info : public MethodContext::Info { };
+    class Info : public MethodContext::Info {
+    public:
+      Info(object_type type) : MethodContext::Info(type) { }
+    };
   };
 
+  template &lt;&gt;
+    static bool kind_of&lt;MethodContext&gt;(OBJECT obj) {
+      return obj-&gt;obj_type == MethodContext::type ||
+        obj-&gt;obj_type == BlockContext::type;
+    }
+
 }
 
 #endif</diff>
      <filename>vm/builtin_contexts.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -11,6 +11,17 @@ namespace rubinius {
     return flt;
   }
 
+  OBJECT Float::compare(STATE, Float* other) {
+    double b = other-&gt;to_double();
+    if(val &lt; b) {
+      return Object::i2n(-1);
+    } else if(val &gt; b) {
+      return Object::i2n(1);
+    } else {
+      return Object::i2n(0);
+    }
+  }
+
   Float* Float::coerce(STATE, OBJECT value) {
     if(value-&gt;fixnum_p()) {
       return Float::create(state, (double)(as&lt;Fixnum&gt;(value)-&gt;to_nint()));</diff>
      <filename>vm/builtin_float.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -17,13 +17,15 @@ namespace rubinius {
     static bool is_a(OBJECT obj) {
       return obj-&gt;obj_type == FloatType;
     }
-    
+
     double val;
 
     static Float* create(STATE, double val);
     static Float* coerce(STATE, OBJECT value);
     double to_double(STATE) { return val; }
+    double to_double() { return val; }
     void into_string(STATE, char* buf, size_t sz);
+    OBJECT compare(STATE, Float* other);
 
     static int radix()      { return FLT_RADIX; }
     static int rounds()     { return FLT_ROUNDS; }
@@ -36,6 +38,11 @@ namespace rubinius {
     static int dig()        { return DBL_DIG; }
     static int mant_dig()   { return DBL_MANT_DIG; }
     static double epsilon() { return DBL_EPSILON; }
+
+    class Info : public TypeInfo {
+    public:
+      Info(object_type type) : TypeInfo(type) { }
+    };
   };
 }
 </diff>
      <filename>vm/builtin_float.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -1,8 +1,6 @@
 #include &quot;builtin.hpp&quot;
 
-#define MAX_DENSITY 0.75
 #define find_bin(hash, total) (hash &amp; (total - 1))
-#define hash_redistribute_p(hash) (hash-&gt;entries-&gt;n2i() &gt;= MAX_DENSITY * hash-&gt;bins-&gt;n2i())
 
 #define CSM_SIZE 12
 namespace rubinius {
@@ -26,8 +24,8 @@ namespace rubinius {
   Hash* Hash::dup(STATE) {
     size_t size, i;
     Hash *dup;
-    OBJECT tmp, ent, next;
-    Tuple *vals, *lst;
+    OBJECT tmp;
+    Tuple *vals, *lst, *ent, *next;
 
     size = bins-&gt;n2i();
     dup = Hash::create(state, size);
@@ -42,26 +40,26 @@ namespace rubinius {
     SET(dup, values, vals);
 
     for(i = 0; i &lt; size; i++) {
-      tmp = (Tuple*)values-&gt;at(i);
-      if(tmp-&gt;nil_p()) continue;
+      tmp = try_as&lt;Tuple&gt;(values-&gt;at(i));
+      if(!tmp) continue;
 
-      ent = tmp-&gt;dup(state);
+      ent = as&lt;Tuple&gt;(tmp-&gt;dup(state));
       vals-&gt;put(state, i, ent);
-      next = ent-&gt;at(3);
-      lst = (Tuple*)ent;
+      next = try_as&lt;Tuple&gt;(ent-&gt;at(3));
+      lst = ent;
 
-      while(!next-&gt;nil_p()) {
-        next = next-&gt;dup(state);
+      while(next) {
+        next = as&lt;Tuple&gt;(next-&gt;dup(state));
         lst-&gt;put(state, 3, next);
-        lst = (Tuple*)next;
-        next = next-&gt;at(3);
+        lst = next;
+        next = try_as&lt;Tuple&gt;(next-&gt;at(3));
       }
     }
 
     return dup;
   }
 
-  OBJECT Hash::entry_new(STATE, hashval hsh, OBJECT key, OBJECT data) {
+  Tuple* Hash::entry_new(STATE, hashval hsh, OBJECT key, OBJECT data) {
     Tuple* tup = Tuple::create(state, 4);
     tup-&gt;put(state, 0, Object::i2n(hsh));
     tup-&gt;put(state, 1, key);
@@ -70,14 +68,14 @@ namespace rubinius {
     return tup;
   }
 
-  OBJECT Hash::entry_append(STATE, OBJECT top, OBJECT nxt) {
+  Tuple* Hash::entry_append(STATE, Tuple* top, Tuple* nxt) {
     int depth = 1;
-    Tuple* cur = (Tuple*)top-&gt;at(3);
-    Tuple* last = (Tuple*)top;
+    Tuple* cur = try_as&lt;Tuple&gt;(top-&gt;at(3));
+    Tuple* last = top;
 
-    while(!cur-&gt;nil_p()) {
+    while(cur) {
       last = cur;
-      cur = (Tuple*)cur-&gt;at(3);
+      cur = try_as&lt;Tuple&gt;(cur-&gt;at(3));
       depth++;
     }
 
@@ -85,17 +83,13 @@ namespace rubinius {
     return nxt;
   }
 
-  OBJECT Hash::add_entry(STATE, hashval hsh, OBJECT ent) {
-    OBJECT entry;
-
+  OBJECT Hash::add_entry(STATE, hashval hsh, Tuple* ent) {
     size_t bin = find_bin(hsh, bins-&gt;n2i());
 
-    entry = values-&gt;at(bin);
-
-    if(entry-&gt;nil_p()) {
-      values-&gt;put(state, bin, ent);
-    } else {
+    if(Tuple* entry = try_as&lt;Tuple&gt;(values-&gt;at(bin))) {
       entry_append(state, entry, ent);
+    } else {
+      values-&gt;put(state, bin, ent);
     }
 
     entries = Object::i2n(entries-&gt;n2i() + 1);
@@ -112,20 +106,18 @@ namespace rubinius {
     Tuple* new_values = Tuple::create(state, size);
 
     for(size_t i = 0; i &lt; num; i++) {
-      Tuple* entry = (Tuple*)values-&gt;at(i);
+      Tuple* entry = try_as&lt;Tuple&gt;(values-&gt;at(i));
 
-      while(!entry-&gt;nil_p()) {
-        Tuple* next = (Tuple*)entry-&gt;at(3);
+      while(entry) {
+        Tuple* next = try_as&lt;Tuple&gt;(entry-&gt;at(3));
         entry-&gt;put(state, 3, Qnil);
 
         native_int hash = as&lt;Integer&gt;(entry-&gt;at(0))-&gt;n2i();
         size_t bin = find_bin(hash, size);
-        OBJECT slot = new_values-&gt;at(bin);
-
-        if(slot-&gt;nil_p()) {
-          new_values-&gt;put(state, bin, entry);
-        } else {
+        if(Tuple* slot = try_as&lt;Tuple&gt;(new_values-&gt;at(bin))) {
           entry_append(state, slot, entry);
+        } else {
+          new_values-&gt;put(state, bin, entry);
         }
 
         entry = next;
@@ -136,25 +128,29 @@ namespace rubinius {
     bins = Object::i2n(size);
   }
 
-  OBJECT Hash::find_entry(STATE, hashval hsh) {
+  /* Find the entry that has a hash value of +hsh+. Return NULL if nothing
+   * found. */
+  Tuple* Hash::find_entry(STATE, hashval hsh) {
     size_t num = bins-&gt;n2i();
     size_t bin = find_bin(hsh, num);
-    OBJECT entry = values-&gt;at(bin);
+    Tuple* entry = try_as&lt;Tuple&gt;(values-&gt;at(bin));
+    if(!entry) return NULL;
 
-    while(!entry-&gt;nil_p()) {
+    for(;;) {
       INTEGER th = as&lt;Integer&gt;(entry-&gt;at(0));
       if((hashval)th-&gt;n2i() == hsh) {
         return entry;
       }
-      entry = entry-&gt;at(3);
+
+      if((entry = try_as&lt;Tuple&gt;(entry-&gt;at(3))) == NULL) return NULL;
     }
-    return Qnil;
+    return NULL;
   }
 
   OBJECT Hash::add(STATE, hashval hsh, OBJECT key, OBJECT data) {
-    Tuple* entry = (Tuple*)find_entry(state, hsh);
+    Tuple* entry = find_entry(state, hsh);
 
-    if(!entry-&gt;nil_p()) {
+    if(entry) {
       entry-&gt;put(state, 2, data);
       return data;
     }
@@ -171,8 +167,8 @@ namespace rubinius {
   }
 
   OBJECT Hash::get(STATE, hashval hsh) {
-    OBJECT entry = find_entry(state, hsh);
-    if(!entry-&gt;nil_p()) {
+    Tuple* entry = find_entry(state, hsh);
+    if(entry) {
       return entry-&gt;at(2);
     }
 
@@ -183,20 +179,20 @@ namespace rubinius {
    * Uses +==+ to verify the key in the table matches +key+.
    * Return TRUE if key was found, and *value will be filled. */
   int Hash::lookup(STATE, OBJECT key, hashval hash, OBJECT *value) {
-    OBJECT ent, hk;
+    OBJECT hk;
 
-    ent = find_entry(state, hash);
-    if(ent-&gt;reference_p()) {
-      while((hashval)as&lt;Integer&gt;(ent-&gt;at(0))-&gt;n2i() == hash) {
-        hk = ent-&gt;at(1);
-        if(hk == key) {
-          *value = ent-&gt;at(2);
-          return TRUE;
-        }
+    Tuple* ent = find_entry(state, hash);
+    if(!ent) return FALSE;
 
-        ent = ent-&gt;at(3);
-        if(ent-&gt;nil_p()) break;
+    while((hashval)as&lt;Integer&gt;(ent-&gt;at(0))-&gt;n2i() == hash) {
+      hk = ent-&gt;at(1);
+      if(hk == key) {
+        *value = ent-&gt;at(2);
+        return TRUE;
       }
+
+      ent = try_as&lt;Tuple&gt;(ent-&gt;at(3));
+      if(!ent) break;
     }
 
     return FALSE;
@@ -207,20 +203,20 @@ namespace rubinius {
    * Return TRUE if key was found, and *value will be filled. */
   int Hash::lookup2(STATE, int (*compare)(STATE, OBJECT, OBJECT),
       OBJECT key, hashval hash, OBJECT *value) {
-    OBJECT ent, hk;
+    OBJECT hk;
 
-    ent = find_entry(state, hash);
-    if(ent-&gt;reference_p()) {
-      while((hashval)as&lt;Integer&gt;(ent-&gt;at(0))-&gt;n2i() == hash) {
-        hk = ent-&gt;at(1);
-        if(compare(state, hk, key)) {
-          *value = ent-&gt;at(2);
-          return TRUE;
-        }
+    Tuple* ent = find_entry(state, hash);
+    if(!ent) return FALSE;
 
-        ent = ent-&gt;at(3);
-        if(ent-&gt;nil_p()) break;
+    while((hashval)as&lt;Integer&gt;(ent-&gt;at(0))-&gt;n2i() == hash) {
+      hk = ent-&gt;at(1);
+      if(compare(state, hk, key)) {
+        *value = ent-&gt;at(2);
+        return TRUE;
       }
+
+      ent = try_as&lt;Tuple&gt;(ent-&gt;at(3));
+      if(!ent) break;
     }
 
     return FALSE;
@@ -232,8 +228,8 @@ namespace rubinius {
     Tuple* ent;
     Tuple* base;
 
-    base = ent = (Tuple*)find_entry(state, hash);
-    if(ent-&gt;reference_p()) {
+    base = ent = find_entry(state, hash);
+    if(ent) {
       while((hashval)as&lt;Integer&gt;(ent-&gt;at(0))-&gt;n2i() == hash) {
         hk = ent-&gt;at(1);
         if(compare(state, hk, key)) {
@@ -241,8 +237,8 @@ namespace rubinius {
           return;
         }
 
-        ent = (Tuple*)ent-&gt;at(3);
-        if(ent-&gt;nil_p()) break;
+        ent = try_as&lt;Tuple&gt;(ent-&gt;at(3));
+        if(!ent) break;
       }
 
     }
@@ -251,14 +247,14 @@ namespace rubinius {
       redistribute(state);
     }
 
-    if(base-&gt;reference_p()) {
-      ent = (Tuple*)entry_new(state, hash, key, value);
+    if(base) {
+      ent = entry_new(state, hash, key, value);
       entry_append(state, base, ent);
       entries = Object::i2n(entries-&gt;n2i() + 1);
       return;
     }
 
-    ent = (Tuple*)entry_new(state, hash, key, value);
+    ent = entry_new(state, hash, key, value);
     add_entry(state, hash, ent);
   }
 
@@ -268,10 +264,8 @@ namespace rubinius {
    */
 
   OBJECT Hash::get_undef(STATE, hashval hsh) {
-    OBJECT entry;
-
-    entry = find_entry(state, hsh);
-    if(RTEST(entry)) {
+    Tuple* entry = find_entry(state, hsh);
+    if(entry) {
       return entry-&gt;at(2);
     } else {
       return Qundef;
@@ -313,7 +307,7 @@ namespace rubinius {
     return Qnil;
   }
 
-  Hash* Hash::from_tuple(STATE, OBJECT tup) {
+  Hash* Hash::from_tuple(STATE, Tuple* tup) {
     OBJECT key, val;
     int i, fel;
 </diff>
      <filename>vm/builtin_hash.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -11,22 +11,22 @@ namespace rubinius {
     const static size_t fields = 7;
     const static object_type type = HashType;
 
-    OBJECT instance_variables;
-    OBJECT keys;
-    Tuple* values;
-    FIXNUM bins;
-    FIXNUM entries;
-    OBJECT default_value;
-    OBJECT default_proc;
+    OBJECT __ivars__; // slot
+    OBJECT keys; // slot
+    Tuple* values; // slot
+    FIXNUM bins; // slot
+    FIXNUM entries; // slot
+    OBJECT default_value; // slot
+    OBJECT default_proc; // slot
 
     static Hash* create(STATE, size_t size = HASH_MINSIZE);
     void   setup(STATE, size_t size);
     Hash*  dup(STATE);
-    static OBJECT entry_new(STATE, hashval hsh, OBJECT key, OBJECT data);
-    static OBJECT entry_append(STATE, OBJECT top, OBJECT nxt);
-    OBJECT add_entry(STATE, hashval hsh, OBJECT ent);
+    static Tuple* entry_new(STATE, hashval hsh, OBJECT key, OBJECT data);
+    static Tuple* entry_append(STATE, Tuple* top, Tuple* nxt);
+    OBJECT add_entry(STATE, hashval hsh, Tuple* ent);
     void   redistribute(STATE);
-    OBJECT find_entry(STATE, hashval hsh);
+    Tuple* find_entry(STATE, hashval hsh);
     OBJECT add(STATE, hashval hsh, OBJECT key, OBJECT data);
     OBJECT set(STATE, OBJECT key, OBJECT val);
     OBJECT get(STATE, hashval hsh);
@@ -38,14 +38,24 @@ namespace rubinius {
     OBJECT get_undef(STATE, hashval hsh);
     OBJECT remove(STATE, hashval hsh);
 
-    static Hash*  from_tuple(STATE, OBJECT tup);
+    static Hash*  from_tuple(STATE, Tuple* tup);
     static Tuple* csm_new(STATE);
     static OBJECT csm_find(STATE, Tuple* csm, OBJECT key);
     static OBJECT csm_add(STATE, Tuple* csm, OBJECT key, OBJECT val);
     static Hash*  csm_into_hash(STATE, Tuple* csm);
     static LookupTable* csm_into_lookuptable(STATE, Tuple* csm);
 
+    class Info : public TypeInfo {
+    public:
+      Info(object_type type) : TypeInfo(type) { }
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
+    };
+
   };
+
+#define HASH_MAX_DENSITY 0.75
+#define hash_redistribute_p(hash) (hash-&gt;entries-&gt;n2i() &gt;= HASH_MAX_DENSITY * hash-&gt;bins-&gt;n2i())
 };
 
 #endif</diff>
      <filename>vm/builtin_hash.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -6,11 +6,11 @@
 
 namespace rubinius {
   void IO::init(STATE) {
-    GO(iobuffer).set(state-&gt;new_class(&quot;Buffer&quot;, G(object), IO::Buffer::fields, G(io)));
+    GO(iobuffer).set(state-&gt;new_class(&quot;Buffer&quot;, G(object), IOBuffer::fields, G(io)));
   }
 
-  IO::Buffer* IO::Buffer::create(STATE, size_t bytes) {
-    IO::Buffer* buf = (IO::Buffer*)state-&gt;new_object(G(iobuffer));
+  IOBuffer* IOBuffer::create(STATE, size_t bytes) {
+    IOBuffer* buf = (IOBuffer*)state-&gt;new_object(G(iobuffer));
     SET(buf, storage, ByteArray::create(state, bytes));
     SET(buf, total, Object::i2n(bytes));
     SET(buf, used, Object::i2n(0));
@@ -23,4 +23,9 @@ namespace rubinius {
     SET(io, descriptor, Object::i2n(state, fd));
     return io;
   }
+
+  void IO::initialize(STATE, int fd, char* mode) {
+    SET(this, descriptor, Object::i2n(state, fd));
+    SET(this, mode, String::create(state, mode));
+  }
 };</diff>
      <filename>vm/builtin_io.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -1,13 +1,13 @@
 #include &quot;builtin.hpp&quot;
 
 namespace rubinius {
-  ISeq* ISeq::create(STATE, size_t instructions) {
-    ISeq* is = (ISeq*)state-&gt;new_object(G(iseq));
-    is-&gt;instructions = Tuple::create(state, instructions);
+  InstructionSequence* InstructionSequence::create(STATE, size_t instructions) {
+    InstructionSequence* is = (InstructionSequence*)state-&gt;new_object(G(iseq));
+    is-&gt;opcodes = Tuple::create(state, instructions);
     return is;
   }
 
-  void ISeq::post_marshal(STATE) {
+  void InstructionSequence::post_marshal(STATE) {
 
   }
 </diff>
      <filename>vm/builtin_iseq.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -4,16 +4,24 @@
 #include &quot;objects.hpp&quot;
 
 namespace rubinius {
-  class ISeq : public BuiltinType {
+  class InstructionSequence : public BuiltinType {
   public:
-    const static size_t fields = 2;
+    const static size_t fields = 3;
     const static object_type type = ISeqType;
 
-    OBJECT instance_variables;
-    Tuple* instructions;
+    OBJECT __ivars__; // slot
+    Tuple* opcodes; // slot
+    FIXNUM stack_depth; // slot
 
     void post_marshal(STATE);
-    static ISeq* create(STATE, size_t instructions);
+    static InstructionSequence* create(STATE, size_t instructions);
+
+    class Info : public TypeInfo {
+    public:
+      Info(object_type type) : TypeInfo(type) { }
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
+    };
 
 #include &quot;gen/iseq_instruction_names.hpp&quot;
   };</diff>
      <filename>vm/builtin_iseq.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -10,22 +10,24 @@ namespace rubinius {
     cls-&gt;set_object_type(ListType);
 
     GO(list_node).set(state-&gt;new_class(&quot;Node&quot;, G(object),
-                                                List::Node::fields, cls));
+                                                ListNode::fields, cls));
+
+    G(list_node)-&gt;set_object_type(ListNodeType);
   }
 
   /* Create a new List object, containing no elements. */
   List* List::create(STATE) {
     List* list = (List*)state-&gt;new_object(G(list));
-    list-&gt;count = Object::i2n(0);
+    SET(list, count, Object::i2n(0));
 
     return list;
   }
 
   /* Append +obj+ to the current List. */
   void List::append(STATE, OBJECT obj) {
-    List::Node* node = (List::Node*)state-&gt;new_object(G(list_node));
+    ListNode* node = (ListNode*)state-&gt;new_object(G(list_node));
     SET(node, object, obj);
-    List::Node* cur_last = last;
+    ListNode* cur_last = last;
 
     if(!cur_last-&gt;nil_p()) {
       SET(cur_last, next, node);
@@ -37,12 +39,12 @@ namespace rubinius {
       SET(this, first, node);
     }
 
-    count = Object::i2n(state, count-&gt;n2i() + 1);
+    SET(this, count, Object::i2n(state, count-&gt;n2i() + 1));
   }
 
   /* Return the +index+ numbered element from the beginning. */
   OBJECT List::locate(STATE, size_t index) {
-    Node* cur = first;
+    ListNode* cur = first;
 
     while(index &gt; 0) {
       if(cur-&gt;nil_p()) return Qnil;
@@ -60,12 +62,12 @@ namespace rubinius {
   OBJECT List::shift(STATE) {
     if(empty_p()) return Qnil;
 
-    count = Object::i2n(state, count-&gt;n2i() - 1);
-    List::Node* n = first;
+    SET(this, count, Object::i2n(state, count-&gt;n2i() - 1));
+    ListNode* n = first;
     SET(this, first, first-&gt;next);
 
     if(last == n) {
-      last = (Node*)Qnil;
+      SET(this, last, Qnil);
     }
 
     return n-&gt;object;
@@ -79,9 +81,9 @@ namespace rubinius {
 
     size_t deleted = 0, counted = 0;
 
-    Node* node = first;
-    Node* lst =  (Node*)Qnil;
-    Node* nxt =  (Node*)Qnil;
+    ListNode* node = first;
+    ListNode* lst =  (ListNode*)Qnil;
+    ListNode* nxt =  (ListNode*)Qnil;
 
     while(!node-&gt;nil_p()) {
       nxt = node-&gt;next;
@@ -98,7 +100,7 @@ namespace rubinius {
           SET(this, last, lst);
         }
 
-        lst = (Node*)Qnil;
+        lst = (ListNode*)Qnil;
       } else {
         counted++;
         lst = node;
@@ -107,7 +109,7 @@ namespace rubinius {
       node = nxt;
     }
 
-    count = Object::i2n(state, counted);
+    SET(this, count, Object::i2n(state, counted));
 
     return deleted;
   }</diff>
      <filename>vm/builtin_list.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -5,24 +5,34 @@
 
 namespace rubinius {
 
-  class List : public BuiltinType {
-    public:
+  class ListNode : public BuiltinType {
+  public:
 
-    class Node : public BuiltinType {
-      public:
+    const static size_t fields = 2;
+    const static object_type type = ListNodeType;
 
-      const static size_t fields = 2;
+    OBJECT object; // slot
+    ListNode* next; // slot
 
-      OBJECT object;
-      Node* next;
+    class Info : public TypeInfo {
+    public:
+      Info(object_type type) : TypeInfo(type) { }
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
     };
-      
-    const static size_t fields = 3;
+
+  };
+
+  class List : public BuiltinType {
+  public:
+
+    const static size_t fields = 4;
     const static object_type type = ListType;
 
-    INTEGER count;
-    Node* first;
-    Node* last;
+    OBJECT __ivars__; // slot
+    INTEGER count; // slot
+    ListNode* first; // slot
+    ListNode* last; // slot
 
     /* Returns true if the List is empty, contains no elements. */
     bool empty_p() {
@@ -40,6 +50,14 @@ namespace rubinius {
     OBJECT shift(STATE);
     OBJECT locate(STATE, size_t index);
     size_t remove(STATE, OBJECT obj);
+
+    class Info : public TypeInfo {
+    public:
+      Info(object_type type) : TypeInfo(type) { }
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
+    };
+
   };
 
 };</diff>
      <filename>vm/builtin_list.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -52,9 +52,9 @@ namespace rubinius {
     state-&gt;om-&gt;set_class(dup, class_object(state));
     size_t num = entries-&gt;n2i();
 
-    Array* entries = (Array*)all_entries(state);
+    Array* entries = all_entries(state);
     for(i = 0; i &lt; num; i++) {
-      OBJECT entry = entries-&gt;get(state, i);
+      Tuple* entry = as&lt;Tuple&gt;(entries-&gt;get(state, i));
       OBJECT key =   entry-&gt;at(0);
       OBJECT value = entry-&gt;at(1);
       dup-&gt;store(state, key, value);
@@ -71,13 +71,13 @@ namespace rubinius {
     return tup;
   }
 
-  OBJECT LookupTable::entry_append(STATE, OBJECT top, OBJECT nxt) {
-    Tuple* cur = (Tuple*)top-&gt;at(2);
-    Tuple* last = (Tuple*)top;
+  OBJECT LookupTable::entry_append(STATE, Tuple* top, OBJECT nxt) {
+    Tuple* cur = try_as&lt;Tuple&gt;(top-&gt;at(2));
+    Tuple* last = top;
 
-    while(!cur-&gt;nil_p()) {
+    while(cur) {
       last = cur;
-      cur = (Tuple*)cur-&gt;at(2);
+      cur = try_as&lt;Tuple&gt;(cur-&gt;at(2));
     }
 
     last-&gt;put(state, 2, nxt);
@@ -96,9 +96,9 @@ namespace rubinius {
         entry-&gt;put(state, 2, Qnil);
 
         size_t bin = find_bin(key_hash(entry-&gt;at(0)), size);
-        OBJECT slot = new_values-&gt;at(bin);
+        Tuple* slot = try_as&lt;Tuple&gt;(new_values-&gt;at(bin));
 
-        if(slot-&gt;nil_p()) {
+        if(!slot) {
           new_values-&gt;put(state, bin, entry);
         } else {
           entry_append(state, slot, entry);
@@ -149,38 +149,32 @@ namespace rubinius {
     return val;
   }
 
-  OBJECT LookupTable::find_entry(STATE, OBJECT key) {
+  Tuple* LookupTable::find_entry(STATE, OBJECT key) {
     unsigned int bin;
-    OBJECT entry;
+    Tuple* entry;
 
     key_to_sym(key);
     bin = find_bin(key_hash(key), bins-&gt;n2i());
-    entry = values-&gt;at(bin);
+    entry = try_as&lt;Tuple&gt;(values-&gt;at(bin));
 
-    while(!entry-&gt;nil_p()) {
+    while(entry) {
       if(entry-&gt;at(0) == key) {
         return entry;
       }
-      entry = entry-&gt;at(2);
+      entry = try_as&lt;Tuple&gt;(entry-&gt;at(2));
     }
-    return Qnil;
+    return NULL;
   }
 
   OBJECT LookupTable::fetch(STATE, OBJECT key) {
-    OBJECT entry;
-
-    entry = find_entry(state, key);
-    if(!entry-&gt;nil_p()) {
-      return entry-&gt;at(1);
-    }
+    Tuple* entry = find_entry(state, key);
+    if(entry) return entry-&gt;at(1);
     return Qnil;
   }
 
   OBJECT LookupTable::fetch(STATE, OBJECT key, bool* found) {
-    OBJECT entry;
-
-    entry = find_entry(state, key);
-    if(!entry-&gt;nil_p()) {
+    Tuple* entry = find_entry(state, key);
+    if(entry) {
       *found = true;
       return entry-&gt;at(1);
     }
@@ -195,10 +189,8 @@ namespace rubinius {
    * in cpu.c in e.g. cpu_const_get_in_context.
    */
   OBJECT LookupTable::find(STATE, OBJECT key) {
-    OBJECT entry;
-
-    entry = find_entry(state, key);
-    if(!entry-&gt;nil_p()) {
+    Tuple* entry = find_entry(state, key);
+    if(entry) {
       return entry-&gt;at(1);
     }
     return Qundef;
@@ -247,35 +239,33 @@ namespace rubinius {
   }
 
   OBJECT LookupTable::has_key(STATE, OBJECT key) {
-    OBJECT entry;
+    Tuple* entry = find_entry(state, key);
 
-    entry = find_entry(state, key);
-    if(!entry-&gt;nil_p()) {
-      return Qtrue;
-    }
+    if(entry) return Qtrue;
     return Qfalse;
   }
 
-  Array* LookupTable::collect(STATE, LookupTable* tbl, OBJECT (*action)(STATE, OBJECT)) {
+  Array* LookupTable::collect(STATE, LookupTable* tbl, OBJECT (*action)(STATE, Tuple*)) {
     size_t i, j;
-    OBJECT values, entry;
+    Tuple* values;
+    Tuple* entry;
 
     Array* ary = Array::create(state, tbl-&gt;entries-&gt;n2i());
     size_t num_bins = tbl-&gt;bins-&gt;n2i();
     values = tbl-&gt;values;
 
     for(i = j = 0; i &lt; num_bins; i++) {
-      entry = values-&gt;at(i);
+      entry = try_as&lt;Tuple&gt;(values-&gt;at(i));
 
-      while(!entry-&gt;nil_p()) {
+      while(entry) {
         ary-&gt;set(state, j++, action(state, entry));
-        entry = entry-&gt;at(2);
+        entry = try_as&lt;Tuple&gt;(entry-&gt;at(2));
       }
     }
     return ary;
   }
 
-  OBJECT LookupTable::get_key(STATE, OBJECT entry) {
+  OBJECT LookupTable::get_key(STATE, Tuple* entry) {
     return entry-&gt;at(0);
   }
 
@@ -283,7 +273,7 @@ namespace rubinius {
     return collect(state, this, get_key);
   }
 
-  OBJECT LookupTable::get_value(STATE, OBJECT entry) {
+  OBJECT LookupTable::get_value(STATE, Tuple* entry) {
     return entry-&gt;at(1);
   }
 
@@ -291,11 +281,11 @@ namespace rubinius {
     return collect(state, this, get_value);
   }
 
-  OBJECT LookupTable::get_entry(STATE, OBJECT entry) {
+  OBJECT LookupTable::get_entry(STATE, Tuple* entry) {
     return entry;
   }
 
-  OBJECT LookupTable::all_entries(STATE) {
+  Array* LookupTable::all_entries(STATE) {
     return collect(state, this, get_entry);
   }
 </diff>
      <filename>vm/builtin_lookuptable.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -114,8 +114,8 @@ namespace rubinius {
   Class* Object::class_object(STATE) {
     if(reference_p()) {
       Class* cls = klass;
-      while(!cls-&gt;nil_p() &amp;&amp; !kind_of&lt;Class&gt;(cls)) {
-        cls = (Class*)cls-&gt;superclass;
+      while(!cls-&gt;nil_p() &amp;&amp; !instance_of&lt;Class&gt;(cls)) {
+        cls = as&lt;Class&gt;(cls-&gt;superclass);
       }
 
       return cls;
@@ -231,29 +231,26 @@ namespace rubinius {
     /* Implements the external ivars table for objects that don't
        have their own space for ivars. */
     if(!reference_p()) {
-      LookupTable* tbl = (LookupTable*)G(external_ivars)-&gt;fetch(state, this);
-      if(!tbl-&gt;nil_p()) {
-        return tbl-&gt;fetch(state, sym);
-      }
+      LookupTable* tbl = try_as&lt;LookupTable&gt;(G(external_ivars)-&gt;fetch(state, this));
+      if(tbl) return tbl-&gt;fetch(state, sym);
       return Qnil;
     } else if(!has_ivars_p()) {
-      MetaClass* meta = (MetaClass*)metaclass(state);
-      LookupTable* tbl = (LookupTable*)meta-&gt;has_ivars;
+      MetaClass* meta = as&lt;MetaClass&gt;(metaclass(state));
+      LookupTable* tbl = try_as&lt;LookupTable&gt;(meta-&gt;has_ivars);
 
-      if(tbl-&gt;nil_p()) return Qnil;
+      if(tbl) return tbl-&gt;fetch(state, sym);
+      return Qnil;
+    }
 
-      return tbl-&gt;fetch(state, sym);
+    /* It's a tuple, use csm */
+    if(Tuple* tup = try_as&lt;Tuple&gt;(((NormalObject*)this)-&gt;instance_variables)) {
+      return Hash::csm_find(state, tup, sym);
     }
 
-    tbl = (LookupTable*)((NormalObject*)this)-&gt;instance_variables;
+    tbl = try_as&lt;LookupTable&gt;(((NormalObject*)this)-&gt;instance_variables);
 
     /* No table, no ivar! */
-    if(tbl-&gt;nil_p()) return Qnil;
-
-    /* It's a tuple, use csm */
-    if(kind_of&lt;Tuple&gt;(tbl)) {
-      return Hash::csm_find(state, (Tuple*)tbl, sym);
-    }
+    if(!tbl) return Qnil;
 
     /* It's a normal hash, no problem. */
     val = tbl-&gt;fetch(state, sym);
@@ -266,20 +263,20 @@ namespace rubinius {
     /* Implements the external ivars table for objects that don't
        have their own space for ivars. */
     if(!reference_p()) {
-      tbl = (LookupTable*)G(external_ivars)-&gt;fetch(state, this);
+      tbl = try_as&lt;LookupTable&gt;(G(external_ivars)-&gt;fetch(state, this));
 
-      if(tbl-&gt;nil_p()) {
-        tbl = (LookupTable*)LookupTable::create(state);
+      if(!tbl) {
+        tbl = LookupTable::create(state);
         G(external_ivars)-&gt;store(state, this, tbl);
       }
       tbl-&gt;store(state, sym, val);
       return val;
     } else if(!has_ivars_p()) {
-      MetaClass* meta = (MetaClass*)metaclass(state);
-      LookupTable* tbl = (LookupTable*)meta-&gt;has_ivars;
+      MetaClass* meta = as&lt;MetaClass&gt;(metaclass(state));
+      tbl = try_as&lt;LookupTable&gt;(meta-&gt;has_ivars);
 
-      if(tbl-&gt;nil_p()) {
-        tbl = (LookupTable*)LookupTable::create(state);
+      if(!tbl) {
+        tbl = LookupTable::create(state);
         SET(meta, has_ivars, tbl);
       }
 
@@ -287,26 +284,27 @@ namespace rubinius {
       return val;
     }
 
-    tbl = (LookupTable*)((NormalObject*)this)-&gt;instance_variables;
+    OBJECT ivars = ((NormalObject*)this)-&gt;instance_variables;
 
     /* Lazy creation of hash to store instance variables. */
-    if(tbl-&gt;nil_p()) {
-      Tuple* tup = (Tuple*)Hash::csm_new(state);
+    if(ivars-&gt;nil_p()) {
+      Tuple* tup = Hash::csm_new(state);
       SET((NormalObject*)this, instance_variables, tup);
       Hash::csm_add(state, tup, sym, val);
       return val;
     }
 
-    if(kind_of&lt;Tuple&gt;(tbl)) {
-      if(Hash::csm_add(state, (Tuple*)tbl, sym, val) == Qtrue) {
+    if(Tuple* tup = try_as&lt;Tuple&gt;(ivars)) {
+      if(Hash::csm_add(state, tup, sym, val) == Qtrue) {
         return val;
       }
       /* csm_add said false, meaning there is no room. We convert
          the csm into a normal hash and use it from now on. */
-      tbl = (LookupTable*)Hash::csm_into_lookuptable(state, (Tuple*)tbl);
+      tbl = Hash::csm_into_lookuptable(state, (Tuple*)tbl);
       SET((NormalObject*)this, instance_variables, tbl);
     }
-    tbl-&gt;store(state, sym, val);
+    
+    as&lt;LookupTable&gt;(ivars)-&gt;store(state, sym, val);
     return val;
   }
 
@@ -323,4 +321,24 @@ namespace rubinius {
   void Object::cleanup(STATE) {
     state-&gt;om-&gt;find_type_info(this)-&gt;cleanup(this);
   }
+
+  void Object::copy_flags(STATE, OBJECT source) {
+    this-&gt;obj_type        = source-&gt;obj_type;
+    this-&gt;CanStoreIvars   = source-&gt;CanStoreIvars;
+    this-&gt;StoresBytes     = source-&gt;StoresBytes;
+    this-&gt;RequiresCleanup = source-&gt;RequiresCleanup;
+    this-&gt;IsBlockContext  = source-&gt;IsBlockContext;
+    this-&gt;IsMeta          = source-&gt;IsMeta;
+  }
+    
+  // 'virtual' methods. They dispatch to the object's TypeInfo
+  // object to perform the work.
+  OBJECT Object::get_field(STATE, size_t index) {
+    return state-&gt;om-&gt;type_info[obj_type]-&gt;get_field(state, this, index);
+  }
+
+  void Object::set_field(STATE, size_t index, OBJECT val) {
+    state-&gt;om-&gt;type_info[obj_type]-&gt;set_field(state, this, index, val);
+  }
+
 }</diff>
      <filename>vm/builtin_object.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -42,7 +42,7 @@ namespace rubinius {
 
     GO(matchdata).set(state-&gt;new_class(&quot;MatchData&quot;, G(object), 0));
 
-    state-&gt;add_type_info(new RegexpData::Info(G(regexpdata)));
+    state-&gt;add_type_info(new RegexpData::Info(RegexpData::type));
   }
 
   char *Regexp::version(STATE) {</diff>
      <filename>vm/builtin_regexp.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,6 @@
 #ifndef RBX_REGEXP_HPP
 #define RBX_REGEXP_HPP
 
-
 namespace rubinius {
   class RegexpData : public BuiltinType {
     public:
@@ -10,32 +9,20 @@ namespace rubinius {
 
     class Info : public TypeInfo {
     public:
-      Info(Class* cls) : TypeInfo(cls) { }
+      Info(object_type type) : TypeInfo(type) { }
       virtual void cleanup(OBJECT obj);
     };
   };
-  
-  class MatchData : public BuiltinType {
-    public:
-    const static size_t fields = 5;
-    const static object_type type = MatchDataType;
 
-    OBJECT instance_variables;
-    OBJECT source;
-    OBJECT regexp;
-    OBJECT full;
-    OBJECT region;
-  };
-  
   class Regexp : public BuiltinType {
     public:
     const static size_t fields = 4;
     const static object_type type = RegexpType;
 
-    OBJECT instance_variables;
-    OBJECT source;
-    OBJECT data;
-    OBJECT names;
+    OBJECT __ivars__; // slot
+    String* source; // slot
+    RegexpData* data; // slot
+    Hash* names; // slot
 
     static void cleanup(STATE, OBJECT data);
     static void init(STATE);
@@ -45,7 +32,34 @@ namespace rubinius {
     OBJECT options(STATE);
     OBJECT match_region(STATE, String* string, INTEGER start, INTEGER end, OBJECT forward);
 
+    class Info : public TypeInfo {
+    public:
+      Info(object_type type) : TypeInfo(type) { }
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
+    };
+
+  };
+
+  class MatchData : public BuiltinType {
+    public:
+    const static size_t fields = 5;
+    const static object_type type = MatchDataType;
+
+    OBJECT __ivars__; // slot
+    String* source; // slot
+    Regexp* regexp; // slot
+    Tuple* full; // slot
+    Tuple* region; // slot
+
+    class Info : public TypeInfo {
+    public:
+      Info(object_type type) : TypeInfo(type) { }
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
+    };
   };
+
 }
 
 #endif</diff>
      <filename>vm/builtin_regexp.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -10,10 +10,12 @@ namespace rubinius {
   class Selector : public BuiltinType {
     public:
 
-    static const size_t fields = 2;
+    static const size_t fields = 3;
+    static const object_type type = SelectorType;
 
-    OBJECT name;
-    Array* send_sites;
+    OBJECT __ivars__; // slot
+    SYMBOL name; // slot
+    Array* send_sites; // slot
 
     static void init(STATE);
     static Selector* create(STATE, OBJECT name);
@@ -24,6 +26,13 @@ namespace rubinius {
     void   clear(STATE);
     bool   includes_p(STATE, SendSite* ss);
 
+    class Info : public TypeInfo {
+    public:
+      Info(object_type type) : TypeInfo(type) { }
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
+    };
+
   };
 };
 </diff>
      <filename>vm/builtin_selector.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -52,7 +52,7 @@ namespace rubinius {
   bool HierarchyResolver::resolve(STATE, Message&amp; msg) {
     Module* module = msg.lookup_from;
     OBJECT entry;
-    CompiledMethod::Visibility* vis;
+    MethodVisibility* vis;
 
     do {
       entry = module-&gt;method_table-&gt;fetch(state, msg.name);
@@ -64,7 +64,7 @@ namespace rubinius {
        * (eg. undef_method) */
       if(entry == Qfalse) return false;
 
-      vis = try_as&lt;CompiledMethod::Visibility&gt;(entry);
+      vis = try_as&lt;MethodVisibility&gt;(entry);
 
       /* If this was a private send, then we can handle use
        * any method seen. */</diff>
      <filename>vm/builtin_sendsite.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -45,7 +45,7 @@ namespace rubinius {
     size_t sz = size(state);
 
     hashval h = hash_str(bp, sz);
-    hash = Object::ui2n(state, h);
+    SET(this, hash, Object::ui2n(state, h));
 
     return h;
   }
@@ -76,8 +76,8 @@ namespace rubinius {
   }
 
   int String::string_equal_p(STATE, OBJECT a, OBJECT b) {
-    String* self = (String*)a;
-    String* other = (String*)b;
+    String* self = as&lt;String&gt;(a);
+    String* other = as&lt;String&gt;(b);
 
     if(self-&gt;bytes != other-&gt;bytes) return FALSE;
     if(strcmp(self-&gt;byte_address(state), other-&gt;byte_address(state))) {
@@ -91,8 +91,8 @@ namespace rubinius {
     String* ns;
 
     ns = (String*)dup(state);
-    ns-&gt;shared = Qtrue;
-    shared = Qtrue;
+    SET(ns, shared, Qtrue);
+    SET(this, shared, Qtrue);
 
     state-&gt;om-&gt;set_class(ns, class_object(state));
 
@@ -100,8 +100,8 @@ namespace rubinius {
   }
 
   void String::unshare(STATE) {
-    data = data-&gt;dup(state);
-    shared = Qfalse;
+    SET(this, data, as&lt;ByteArray&gt;(data-&gt;dup(state)));
+    SET(this, shared, Qfalse);
   }
 
   String* String::append(STATE, String* other) {
@@ -116,8 +116,8 @@ namespace rubinius {
     d2-&gt;bytes[new_size] = 0;
 
     num_bytes = Object::i2n(state, new_size);
-    data = d2;
-    hash = Qnil;
+    SET(this, data, d2);
+    SET(this, hash, Qnil);
 
     return this;
   }
@@ -135,8 +135,8 @@ namespace rubinius {
     d2-&gt;bytes[new_size] = 0;
 
     num_bytes = Object::i2n(state, new_size);
-    data = d2;
-    hash = Qnil;
+    SET(this, data, d2);
+    SET(this, hash, Qnil);
 
     return this;
   }</diff>
      <filename>vm/builtin_string.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -4,19 +4,20 @@
 namespace rubinius {
   class String : public BuiltinType {
     public:
-    const static size_t fields = 6;
+    const static size_t fields = 7;
     const static object_type type = StringType;
 
     static bool is_a(OBJECT obj) {
       return obj-&gt;reference_p() &amp;&amp; obj-&gt;obj_type == StringType;
     }
 
-    INTEGER num_bytes;
-    OBJECT characters;
-    OBJECT encoding;
-    OBJECT data;
-    OBJECT hash;
-    OBJECT shared;
+    OBJECT __ivars__; // slot
+    INTEGER num_bytes; // slot
+    INTEGER characters; // slot
+    OBJECT encoding; // slot
+    ByteArray* data; // slot
+    INTEGER hash; // slot
+    OBJECT shared; // slot
 
     static String* create(STATE, const char* str, size_t bytes = 0);
     static hashval hash_str(const unsigned char *bp, unsigned int sz);
@@ -30,11 +31,6 @@ namespace rubinius {
       return num_bytes-&gt;n2i();
     }
 
-    /* Allows the String object to be cast as a char* */
-    operator const char *() {
-      return (const char*)(data-&gt;bytes);
-    }
-
     /* TODO: since we're technically say it's ok to change this, we might
      * want to copy it first. */
     operator char *() {
@@ -55,6 +51,13 @@ namespace rubinius {
     String* add(STATE, String* other);
     String* add(STATE, char* other);
 
+    class Info : public TypeInfo {
+    public:
+      Info(object_type type) : TypeInfo(type) { }
+      virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
+      virtual OBJECT get_field(STATE, OBJECT target, size_t index);
+    };
+
   };
 };
 </diff>
      <filename>vm/builtin_string.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -20,10 +20,10 @@ namespace rubinius {
     if(!size) size = std::strlen(str);
 
     hashval hash = String::hash_str((unsigned char*)str, size);
-    OBJECT ent = strings-&gt;find_entry(state, hash);
+    Tuple* ent = strings-&gt;find_entry(state, hash);
 
     /* If it wasn't present, use the longer, more correct version. */
-    if(ent-&gt;nil_p() || ent == Qundef) {
+    if(!ent) {
       return lookup(state, String::create(state, str, size));
     }
 </diff>
      <filename>vm/builtin_symbol.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -15,10 +15,7 @@ namespace rubinius {
   }
 
   Task* Task::create(STATE, OBJECT recv, CompiledMethod* meth) {
-    Task* task = (Task*)state-&gt;new_struct(G(task), sizeof(Task));
-    task-&gt;ip = 0;
-    task-&gt;sp = -1;
-    task-&gt;state = state;
+    Task* task = create(state);
     task-&gt;make_active(task-&gt;generate_context(recv, meth));
     return task;
   }
@@ -28,9 +25,16 @@ namespace rubinius {
     task-&gt;ip = 0;
     task-&gt;sp = -1;
     task-&gt;state = state;
+    SET(task, control_channel, Qnil);
+    SET(task, debug_channel, Qnil);
+    SET(task, active, Qnil);
+
     return task;
   }
 
+  void Task::Info::mark(Task* obj) {
+  }
+
   MethodContext* Task::generate_context(OBJECT recv, CompiledMethod* meth) {
     MethodContext* ctx = MethodContext::create(state);
 
@@ -208,9 +212,9 @@ namespace rubinius {
       return (Executable*)Qnil;
     }
 
-    CompiledMethod::Visibility *vis;
+    MethodVisibility *vis;
 
-    vis = try_as&lt;CompiledMethod::Visibility&gt;(msg.method);
+    vis = try_as&lt;MethodVisibility&gt;(msg.method);
     if(vis) {
       return vis-&gt;method;
     }</diff>
      <filename>vm/builtin_task.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -89,9 +89,9 @@ namespace rubinius {
 
     class Info : public TypeInfo {
     public:
+      Info(object_type type) : TypeInfo(type) { }
       virtual void mark(Task* obj);
     };
-
   };
 }
 </diff>
      <filename>vm/builtin_task.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -20,4 +20,18 @@ namespace rubinius {
     SET(thr, priority, Object::i2n(2));
     return thr;
   }
+
+  void Thread::boot_task(STATE) {
+    Task* task = Task::create(state);
+    SET(this, task, task);
+  }
+
+  void Thread::set_top(STATE, OBJECT val) {
+    task-&gt;stack-&gt;put(state, task-&gt;sp, val);
+  }
+  
+  void Thread::sleep_for(STATE, Channel* chan) {
+    channel = chan;
+    set_ivar(state, state-&gt;symbol(&quot;@sleep&quot;), Qtrue);
+  }
 }</diff>
      <filename>vm/builtin_thread.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -7,13 +7,16 @@ namespace rubinius {
     const static size_t fields = 5;
     const static object_type type = ThreadType;
 
+    OBJECT ivars;
     Task* task;
     Channel* channel;
     FIXNUM priority;
 
     static void init(STATE);
     static Thread* create(STATE);
+    void boot_task(STATE);
     void sleep_for(STATE, Channel* chan);
+    void set_top(STATE, OBJECT val);
   };
 
   class DeadLock : public Assertion {</diff>
      <filename>vm/builtin_thread.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -75,7 +75,7 @@ namespace rubinius {
       ev.data = this;
     }
 
-    void Read::into_buffer(rubinius::IO::Buffer *buf, size_t bytes) {
+    void Read::into_buffer(rubinius::IOBuffer *buf, size_t bytes) {
       count = bytes;
       buffer.set(buf);
     }</diff>
      <filename>vm/event.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -18,7 +18,7 @@ namespace rubinius {
       STATE;
       ObjectCallback* channel;
       size_t id;
-      TypedRoot&lt;IO::Buffer*&gt; buffer;
+      TypedRoot&lt;IOBuffer*&gt; buffer;
       Loop* loop;
 
       Event(STATE, ObjectCallback* chan);
@@ -57,7 +57,7 @@ namespace rubinius {
 
       Read(STATE, ObjectCallback* chan, int fd);
       virtual ~Read() { }
-      void into_buffer(rubinius::IO::Buffer* buffer, size_t bytes);
+      void into_buffer(rubinius::IOBuffer* buffer, size_t bytes);
       virtual bool activated();
     };
 </diff>
      <filename>vm/event.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -21,50 +21,9 @@
 #define RBX_FFI_TYPE_STRPTR  17
 #define RBX_FFI_TYPE_CHARARR 18
 
-#include &lt;ffi.h&gt;
 #include &quot;prelude.hpp&quot;
 #include &quot;object.hpp&quot;
 #include &quot;message.hpp&quot;
 
-namespace rubinius {
-  class MemoryPointer : public BuiltinType {
-    public:
-    const static size_t fields = 0;
-    const static object_type type = MemPtrType;
-
-    void* pointer;
-
-    static MemoryPointer* create(STATE, void* ptr);
-
-    OBJECT get_field(STATE, int offset, int type);
-    void   set_field(STATE, int offset, int type, OBJECT val);
-  };
-
-  class NativeFunction : public Executable {
-    public:
-    struct ffi_stub {
-      ffi_cif cif;
-      size_t arg_count;
-      int *arg_types;
-      int ret_type;
-      void *ep;
-    };
-
-    static const size_t fields = 7;
-    OBJECT name;
-    String* file;
-    MemoryPointer* data;
-
-    static void* find_symbol(STATE, OBJECT library, String* name);
-
-    static size_t type_size(size_t type);
-    static NativeFunction* create(STATE, OBJECT name, int args);
-    void bind(STATE, int arg_count, int *arg_types, int ret_type, void* func);
-    static NativeFunction* bind(STATE, String* library, String* name, Array* args, OBJECT ret);
-    void **marshal_arguments(STATE, Message *msg);
-    OBJECT call(STATE, Message* msg);
-  };
-
-}
 
 #endif</diff>
      <filename>vm/ffi.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -49,9 +49,9 @@ namespace rubinius {
       entry-&gt;name = name;
       entry-&gt;module = mod;
 
-      if(kind_of&lt;CompiledMethod::Visibility&gt;(meth)) {
-        CompiledMethod::Visibility* vis;
-        vis = as&lt;CompiledMethod::Visibility&gt;(meth);
+      if(kind_of&lt;MethodVisibility&gt;(meth)) {
+        MethodVisibility* vis;
+        vis = as&lt;MethodVisibility&gt;(meth);
 
         if(vis-&gt;public_p(state)) {
           entry-&gt;is_public = true;</diff>
      <filename>vm/global_cache.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -55,6 +55,7 @@ namespace rubinius {
     TypedRoot&lt;Module*&gt; vm;
     TypedRoot&lt;Thread*&gt; current_thread;
     TypedRoot&lt;Task*&gt; current_task;
+    TypedRoot&lt;OBJECT&gt; main;
 
     /* Leave this as the last data member always */
     TypedRoot&lt;Class*&gt; special_classes[SPECIAL_CLASS_SIZE];
@@ -99,7 +100,8 @@ namespace rubinius {
       top_scope(&amp;roots), on_gc_channel(&amp;roots),
       vm(&amp;roots),
       current_thread(&amp;roots),
-      current_task(&amp;roots)
+      current_task(&amp;roots),
+      main(&amp;roots)
     { }
   };
 };</diff>
      <filename>vm/globals.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -72,7 +72,7 @@ class TestInstructions : public CxxTest::TestSuite {
         fd.puts &quot;void #{meth}() {&quot;
         fd.puts &quot;Task* task = Task::create(state);&quot;
         fd.puts &quot;CompiledMethod* cm = CompiledMethod::create(state);&quot;
-        fd.puts &quot;cm-&gt;iseq = ISeq::create(state, 10);&quot;
+        fd.puts &quot;cm-&gt;iseq = InstructionSequence::create(state, 10);&quot;
         fd.puts &quot;cm-&gt;stack_size = Object::i2n(10);&quot;
         fd.puts &quot;MethodContext* ctx = task-&gt;generate_context(Qnil, cm);&quot;
         fd.puts &quot;task-&gt;make_active(ctx);&quot;
@@ -80,7 +80,7 @@ class TestInstructions : public CxxTest::TestSuite {
         fd.puts &quot;Tuple* stack = task-&gt;stack; stack += 0;&quot;
         fd.puts &quot;task-&gt;literals = Tuple::create(state, 10);&quot;
         fd.puts &quot;opcode stream[100];&quot;
-        fd.puts &quot;stream[0] = ISeq::insn_#{ins.opcode};&quot;
+        fd.puts &quot;stream[0] = InstructionSequence::insn_#{ins.opcode};&quot;
         fd.puts &quot;#define run(val) task-&gt;execute_stream(stream)&quot;
         fd.puts &quot;#line #{line} \&quot;instructions.rb\&quot;&quot;
         fd.puts code
@@ -197,7 +197,7 @@ class TestInstructions : public CxxTest::TestSuite {
   end
 
   def generate_names
-    str =  &quot;const char *rubinius::ISeq::get_instruction_name(int op) {\n&quot;
+    str =  &quot;const char *rubinius::InstructionSequence::get_instruction_name(int op) {\n&quot;
     str &lt;&lt; &quot;static const char instruction_names[] = {\n&quot;
     InstructionSet::OpCodes.each do |ins|
       str &lt;&lt; &quot;  \&quot;#{ins.opcode.to_s}\\0\&quot;\n&quot;
@@ -852,88 +852,6 @@ CODE
   end
 
   # [Operation]
-  #   Store a value into the specified object field
-  # [Format]
-  #   \store_field
-  # [Stack Before]
-  #   * field
-  #   * value
-  #   * object
-  #   * ...
-  # [Stack After]
-  #   * object
-  #   * ...
-  # [Description]
-  #   Overwrite the value of a particular field slot with the specified
-  #   object. The object reference is left on the stack.
-
-  def store_field
-    &lt;&lt;-CODE
-    t1 = stack_pop();
-    t2 = stack_pop();
-    t3 = stack_pop();
-    size_t idx = (size_t)as&lt;Fixnum&gt;(t1)-&gt;n2i();
-    check_bounds(t3, idx);
-    SET(t3, field[idx], t2);
-    stack_push(t3);
-    CODE
-  end
-
-  def test_store_field
-    &lt;&lt;-CODE
-    Tuple* tup = Tuple::create(state, 3);
-    tup-&gt;put(state, 0, Qnil);
-
-    stack-&gt;put(state, ++task-&gt;sp, tup);
-    stack-&gt;put(state, ++task-&gt;sp, Qtrue);
-    stack-&gt;put(state, ++task-&gt;sp, Object::i2n(0));
-
-    run();
-
-    TS_ASSERT_EQUALS(tup-&gt;at(0), Qtrue);
-    CODE
-  end
-
-  # [Operation]
-  #   Retrieve the value within the field of the specified object
-  # [Format]
-  #   \fetch_field
-  # [Stack Before]
-  #   * field
-  #   * object
-  #   * ...
-  # [Stack After]
-  #   * value
-  #   * ...
-  # [Description]
-  #   Retrieve the object of the specified object field number.
-
-  def fetch_field
-    &lt;&lt;-CODE
-    t1 = stack_pop();
-    t2 = stack_pop();
-    size_t index = as&lt;Fixnum&gt;(t1)-&gt;n2i();
-    check_bounds(t2, index);
-    stack_push(t2-&gt;at(index));
-    CODE
-  end
-
-  def test_fetch_field
-    &lt;&lt;-CODE
-    Tuple* tup = Tuple::create(state, 3);
-    tup-&gt;put(state, 0, Qtrue);
-
-    stack-&gt;put(state, ++task-&gt;sp, tup);
-    stack-&gt;put(state, ++task-&gt;sp, Object::i2n(0));
-
-    run();
-
-    TS_ASSERT_EQUALS(task-&gt;sp, 0);
-    TS_ASSERT_EQUALS(stack-&gt;at(task-&gt;sp), Qtrue);
-    CODE
-  end
-
-  # [Operation]
   #   Pushes a value from an object field onto the stack
   # [Format]
   #   \push_my_field fld
@@ -953,7 +871,7 @@ CODE
   def push_my_field
     &lt;&lt;-CODE
     next_int;
-    stack_push(self-&gt;at(_int));
+    stack_push(self-&gt;get_field(state, _int));
     CODE
   end
 
@@ -965,10 +883,20 @@ CODE
     task-&gt;self = tup;
 
     stream[1] = (opcode)0;
+
+    TS_ASSERT_THROWS(run(), std::runtime_error);
+
+    Class* cls = state-&gt;new_class(&quot;Blah&quot;);
+
+    task-&gt;self = cls;
+
+    stream[1] = (opcode)2;
+
+    task-&gt;sp = -1;
     run();
 
     TS_ASSERT_EQUALS(task-&gt;sp, 0);
-    TS_ASSERT_EQUALS(stack-&gt;at(task-&gt;sp), Qtrue);
+    TS_ASSERT_EQUALS(stack-&gt;at(task-&gt;sp), state-&gt;symbol(&quot;Blah&quot;));
     CODE
   end
 
@@ -2359,7 +2287,7 @@ CODE
   def test_send_method
     &lt;&lt;-CODE
     CompiledMethod* target = CompiledMethod::create(state);
-    target-&gt;iseq = ISeq::create(state, 0);
+    target-&gt;iseq = InstructionSequence::create(state, 0);
     target-&gt;total_args = Object::i2n(0);
     target-&gt;required_args = target-&gt;total_args;
     target-&gt;stack_size = Object::i2n(10);
@@ -2451,7 +2379,7 @@ CODE
   def test_send_stack
     &lt;&lt;-CODE
     CompiledMethod* target = CompiledMethod::create(state);
-    target-&gt;iseq = ISeq::create(state, 0);
+    target-&gt;iseq = InstructionSequence::create(state, 0);
     target-&gt;total_args = Object::i2n(1);
     target-&gt;required_args = target-&gt;total_args;
     target-&gt;stack_size = Object::i2n(1);
@@ -2521,7 +2449,7 @@ CODE
   def test_send_stack_with_block
     &lt;&lt;-CODE
     CompiledMethod* target = CompiledMethod::create(state);
-    target-&gt;iseq = ISeq::create(state, 0);
+    target-&gt;iseq = InstructionSequence::create(state, 0);
     target-&gt;total_args = Object::i2n(1);
     target-&gt;required_args = target-&gt;total_args;
     target-&gt;stack_size = Object::i2n(1);
@@ -2612,7 +2540,7 @@ CODE
   def test_send_stack_with_splat
     &lt;&lt;-CODE
     CompiledMethod* target = CompiledMethod::create(state);
-    target-&gt;iseq = ISeq::create(state, 0);
+    target-&gt;iseq = InstructionSequence::create(state, 0);
     target-&gt;total_args = Object::i2n(2);
     target-&gt;required_args = target-&gt;total_args;
     target-&gt;stack_size = Object::i2n(2);
@@ -2687,7 +2615,7 @@ CODE
   def test_send_super_stack_with_block
     &lt;&lt;-CODE
     CompiledMethod* target = CompiledMethod::create(state);
-    target-&gt;iseq = ISeq::create(state, 0);
+    target-&gt;iseq = InstructionSequence::create(state, 0);
     target-&gt;total_args = Object::i2n(1);
     target-&gt;required_args = target-&gt;total_args;
     target-&gt;stack_size = Object::i2n(1);
@@ -2780,7 +2708,7 @@ CODE
   def test_send_super_stack_with_splat
     &lt;&lt;-CODE
     CompiledMethod* target = CompiledMethod::create(state);
-    target-&gt;iseq = ISeq::create(state, 0);
+    target-&gt;iseq = InstructionSequence::create(state, 0);
     target-&gt;total_args = Object::i2n(2);
     target-&gt;required_args = target-&gt;total_args;
     target-&gt;stack_size = Object::i2n(2);
@@ -3340,16 +3268,15 @@ perform_no_ss_send:
 
   def shift_tuple
     &lt;&lt;-CODE
-    t1 = stack_pop();
-    sassert(t1-&gt;reference_p());
+    Tuple* tup = as&lt;Tuple&gt;(stack_pop());
     if(NUM_FIELDS(t1) == 0) {
-      stack_push(t1);
+      stack_push(tup);
       stack_push(Qnil);
     } else {
       j = NUM_FIELDS(t1) - 1;
-      t3 = t1-&gt;at(0);
+      t3 = tup-&gt;at(0);
       Tuple* tup = Tuple::create(state, j);
-      tup-&gt;copy_from(state, as&lt;Tuple&gt;(t1), 1, j);
+      tup-&gt;copy_from(state, tup, 1, j);
       stack_push(t2);
       stack_push(t3);
     }</diff>
      <filename>vm/instructions.rb</filename>
    </modified>
    <modified>
      <diff>@@ -36,32 +36,45 @@ namespace rubinius {
     stream &gt;&gt; count;
     String* str = String::create(state, NULL, count + 1);
 
-    stream &gt;&gt; (char*)*str;
+    stream.get(); // read off newline
+    stream.read((char*)*str, count);
+    stream.get(); // read off newline
 
     return str;
   }
 
   void Marshaller::set_symbol(SYMBOL sym) {
     String* str = sym-&gt;to_str(state);
-    stream &lt;&lt; &quot;x&quot; &lt;&lt; endl &lt;&lt; (char*)*str &lt;&lt; endl;
+    stream &lt;&lt; &quot;x&quot; &lt;&lt; endl &lt;&lt; str-&gt;size() &lt;&lt; endl;
+    stream.write((char*)*str, str-&gt;size()) &lt;&lt; endl;
   }
 
   SYMBOL UnMarshaller::get_symbol() {
     char data[1024];
+    size_t count;
 
-    stream &gt;&gt; data;
+    stream &gt;&gt; count;
+    stream.get();
+    stream.read(data, count + 1);
+    data[count] = 0; // clamp
 
     return G(symbols)-&gt;lookup(state, data);
   }
 
   void Marshaller::set_sendsite(SendSite* ss) {
     String* str = ss-&gt;name-&gt;to_str(state);
-    stream &lt;&lt; &quot;S&quot; &lt;&lt; endl &lt;&lt; (char*)*str &lt;&lt; endl;
+    stream &lt;&lt; &quot;S&quot; &lt;&lt; endl &lt;&lt; str-&gt;size() &lt;&lt; endl;
+    stream.write((char*)*str, str-&gt;size()) &lt;&lt; endl;
   }
 
   SendSite* UnMarshaller::get_sendsite() {
     char data[1024];
-    stream &gt;&gt; data;
+    size_t count;
+
+    stream &gt;&gt; count;
+    stream.get();
+    stream.read(data, count + 1);
+    data[count] = 0; // clamp
 
     SYMBOL sym = G(symbols)-&gt;lookup(state, data);
 
@@ -123,17 +136,26 @@ namespace rubinius {
     return Float::create(state, val);
   }
 
-  void Marshaller::set_iseq(ISeq* iseq) {
-    stream &lt;&lt; &quot;i&quot; &lt;&lt; endl &lt;&lt; iseq-&gt;body_in_bytes() &lt;&lt; endl;
-    stream.write(iseq-&gt;bytes, iseq-&gt;body_in_bytes()) &lt;&lt; endl;
+  void Marshaller::set_iseq(InstructionSequence* iseq) {
+    Tuple* ops = iseq-&gt;opcodes;
+    stream &lt;&lt; &quot;i&quot; &lt;&lt; endl &lt;&lt; ops-&gt;field_count &lt;&lt; endl;
+    for(size_t i = 0; i &lt; ops-&gt;field_count; i++) {
+      stream &lt;&lt; as&lt;Fixnum&gt;(ops-&gt;at(i))-&gt;to_nint() &lt;&lt; endl;
+    }
   }
 
-  ISeq* UnMarshaller::get_iseq() {
-    size_t bytes;
-    stream &gt;&gt; bytes;
+  InstructionSequence* UnMarshaller::get_iseq() {
+    size_t count;
+    long op;
+    stream &gt;&gt; count;
 
-    ISeq* iseq = ISeq::create(state, bytes);
-    stream.read(iseq-&gt;bytes, bytes);
+    InstructionSequence* iseq = InstructionSequence::create(state, count);
+    Tuple* ops = iseq-&gt;opcodes;
+
+    for(size_t i = 0; i &lt; count; i++) {
+      stream &gt;&gt; op;
+      ops-&gt;put(state, i, Object::i2n(op));
+    }
 
     iseq-&gt;post_marshal(state);
 
@@ -141,11 +163,7 @@ namespace rubinius {
   }
 
   void Marshaller::set_cmethod(CompiledMethod* cm) {
-    stream &lt;&lt; &quot;M&quot; &lt;&lt; endl &lt;&lt; 1 &lt;&lt; endl;
-
-    for(size_t i = 0; i &lt; CompiledMethod::saved_fields; i++) {
-      marshal(cm-&gt;at(i));
-    }
+    assert(0);
   }
 
   CompiledMethod* UnMarshaller::get_cmethod() {
@@ -154,9 +172,20 @@ namespace rubinius {
 
     CompiledMethod* cm = CompiledMethod::create(state);
 
-    for(size_t i = 0; i &lt; CompiledMethod::saved_fields; i++) {
-      SET(cm, field[i], unmarshal());
-    }
+    SET(cm, __ivars__, unmarshal());
+    SET(cm, primitive, unmarshal());
+    SET(cm, name,      unmarshal());
+    SET(cm, iseq,      unmarshal());
+    SET(cm, stack_size, unmarshal());
+    SET(cm, local_count, unmarshal());
+    SET(cm, required_args, unmarshal());
+    SET(cm, total_args, unmarshal());
+    SET(cm, splat,     unmarshal());
+    SET(cm, literals,  unmarshal());
+    SET(cm, exceptions, unmarshal());
+    SET(cm, lines,     unmarshal());
+    SET(cm, file,      unmarshal());
+    SET(cm, local_names, unmarshal());
 
     cm-&gt;post_marshal(state);
 
@@ -165,6 +194,7 @@ namespace rubinius {
 
   OBJECT UnMarshaller::unmarshal() {
     char code;
+    
     stream &gt;&gt; code;
 
     switch(code) {
@@ -220,8 +250,8 @@ namespace rubinius {
       set_tuple(as&lt;Tuple&gt;(obj));
     } else if(kind_of&lt;Float&gt;(obj)) {
       set_float(as&lt;Float&gt;(obj));
-    } else if(kind_of&lt;ISeq&gt;(obj)) {
-      set_iseq(as&lt;ISeq&gt;(obj));
+    } else if(kind_of&lt;InstructionSequence&gt;(obj)) {
+      set_iseq(as&lt;InstructionSequence&gt;(obj));
     } else if(kind_of&lt;CompiledMethod&gt;(obj)) {
       set_cmethod(as&lt;CompiledMethod&gt;(obj));
     } else {</diff>
      <filename>vm/marshal.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -30,7 +30,7 @@ namespace rubinius {
     void set_tuple(Tuple* o);
     void set_bignum(Bignum* o);
     void set_float(Float* o);
-    void set_iseq(ISeq* o);
+    void set_iseq(InstructionSequence* o);
     void set_cmethod(CompiledMethod* o);
   };
 
@@ -52,7 +52,7 @@ namespace rubinius {
     Tuple* get_tuple();
 
     Float* get_float();
-    ISeq* get_iseq();
+    InstructionSequence* get_iseq();
     CompiledMethod* get_cmethod();
   };
 }</diff>
      <filename>vm/marshal.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -76,6 +76,7 @@ to be a simple test for that bit pattern.
 #define REFERENCE_P(v) (TAG(v) == TAG_REF)
 
 #define INDEXED(obj) (REFERENCE_P(obj) &amp;&amp; !obj-&gt;StoresBytes)
+#define STORE_BYTES(obj) (REFERENCE_P(obj) &amp;&amp; obj-&gt;StoresBytes)
 
 #define SIZE_OF_OBJECT ((size_t)(sizeof(OBJECT)))
 
@@ -91,7 +92,13 @@ to be a simple test for that bit pattern.
   /* rubinius_object types, takes up 3 bits */
   typedef enum
   {
-    ObjectType      = 0,
+    InvalidType     = 0,
+    NumericType     ,
+    IntegerType     ,
+    FalseType       ,
+    TrueType        ,
+    NilType         ,
+    ObjectType      ,
     MContextType    ,
     BContextType    ,
     ClassType       ,
@@ -108,7 +115,6 @@ to be a simple test for that bit pattern.
     SymbolType      ,
     CMethodType     ,
     NMethodType     ,
-    NilType         ,
     BlockEnvType    ,
     TupleType       ,
     ArrayType       ,
@@ -132,6 +138,8 @@ to be a simple test for that bit pattern.
     ExecutableType  ,
     CMVisibilityType,
     ListType        ,
+    ListNodeType    ,
+    NativeFuncType  ,
 
     LastObjectType   // must remain at end
   } object_type;
@@ -295,13 +303,6 @@ to be a simple test for that bit pattern.
       return zone == MatureObjectZone;
     }
 
-    OBJECT at(size_t index) {
-      if(field_count &lt;= index) {
-        throw new ObjectBoundsExceeded(this, index);
-      }
-      return field[index];
-    }
-
     bool forwarded_p() {
       return Forwarded == 1;
     }
@@ -352,6 +353,8 @@ to be a simple test for that bit pattern.
       return reference_p() &amp;&amp; obj_type == type;
     }
 
+    OBJECT get_field(STATE, size_t index);
+    void   set_field(STATE, size_t index, OBJECT val);
     void cleanup(STATE);
 
     bool kind_of_p(STATE, OBJECT cls);
@@ -365,6 +368,10 @@ to be a simple test for that bit pattern.
     OBJECT get_ivar(STATE, OBJECT sym);
     OBJECT set_ivar(STATE, OBJECT sym, OBJECT val);
 
+    void copy_flags(STATE, OBJECT other);
+    void copy_ivars(STATE, OBJECT other);
+    void copy_metaclass(STATE, OBJECT other);
+
     static const char* type_to_name(object_type type);
   };
 
@@ -374,30 +381,56 @@ to be a simple test for that bit pattern.
 
   /* Given builtin-class +T+, return true if +obj+ is of class +T+ */
   template &lt;class T&gt;
-    static bool kind_of(OBJECT obj) {
+    static inline bool kind_of(OBJECT obj) {
       if(obj-&gt;reference_p()) {
         return obj-&gt;obj_type == T::type;
       }
       return false;
     }
 
+  /* Another version of kind_of that shouldn't be specialized for subtype
+   * compatibility. */
+  template &lt;class T&gt;
+    static inline bool instance_of(OBJECT obj) {
+      if(obj-&gt;reference_p()) {
+        return obj-&gt;obj_type == T::type;
+      }
+      return false;
+    }
+
+  template &lt;&gt;
+    static inline bool kind_of&lt;Object&gt;(OBJECT obj) {
+      return true;
+    }
+
+  template &lt;&gt;
+    static inline bool kind_of&lt;Class&gt;(OBJECT obj) {
+      return obj-&gt;obj_type == ClassType || 
+        obj-&gt;obj_type == MetaclassType ||
+        obj-&gt;obj_type == IncModType;
+    }
+
+
   /* Used when casting between object types.
    *
    * Given builtin class +T+, return +obj+ cast as type +T*+. If
    * +obj+ is not of type +T+, throw's a TypeError exception.
    * */
   template &lt;class T&gt;
-    static T* as(OBJECT obj) {
+    static inline T* as(OBJECT obj) {
       /* The 'obj &amp;&amp;' gives us additional saftey, checking for
        * NULL objects. */
       if(obj &amp;&amp; kind_of&lt;T&gt;(obj)) return (T*)obj;
       throw new TypeError(T::type, obj);
     }
 
+  template &lt;&gt;
+    static inline Object* as&lt;Object&gt;(OBJECT obj) { return obj; }
+
   /* Similar to as&lt;&gt;, but returns NULL if the type is invalid. ONLY
    * use this when doing a conditional cast. */
   template &lt;class T&gt;
-    static T* try_as(OBJECT obj) {
+    static inline T* try_as(OBJECT obj) {
       /* The 'obj &amp;&amp;' gives us additional saftey, checking for
        * NULL objects. */
       if(obj &amp;&amp; kind_of&lt;T&gt;(obj)) return (T*)obj;</diff>
      <filename>vm/object.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -156,7 +156,10 @@ namespace rubinius {
   };
 
 #define SET(obj, field, val) ({ \
-    typeof(obj) _o = (obj); OBJECT  _v = (val); _o-&gt;field = (typeof(_o-&gt;field))_v; state-&gt;om-&gt;write_barrier(_o, _v); })
+    typeof(obj) _o = (obj); OBJECT  _v = (val); \
+    if(_v-&gt;nil_p()) { _o-&gt;field = (typeof(_o-&gt;field))Qnil; } else { \
+    _o-&gt;field = as&lt;typeof(*_o-&gt;field)&gt;(_v); state-&gt;om-&gt;write_barrier(_o, _v); } })
+
 
 #define FREE(obj) free(obj)
 #define ALLOC_N(type, size) ((type*)calloc(size, sizeof(type)))</diff>
      <filename>vm/objectmemory.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -67,7 +67,7 @@ namespace rubinius {
 
     cls-&gt;instance_fields = Object::i2n(Class::fields);
     cls-&gt;has_ivars = Qtrue;
-    cls-&gt;instance_type = Object::i2n(ClassType);
+    cls-&gt;set_object_type(ClassType);
     cls-&gt;obj_type = ClassType;
 
     GO(klass).set(cls);
@@ -130,6 +130,7 @@ namespace rubinius {
     G(blokenv)-&gt;instance_type = Object::i2n(BlockEnvType);
 
     GO(staticscope).set(new_class(object, StaticScope::fields));
+    G(staticscope)-&gt;set_object_type(StaticScopeType);
 
     bootstrap_symbol();
 
@@ -180,7 +181,7 @@ namespace rubinius {
     GO(task).set(new_class(&quot;Task&quot;, object, 0));
     G(task)-&gt;instance_type = Object::i2n(TaskType);
 
-    GO(iseq).set(new_class(&quot;InstructionSequence&quot;, G(object), ISeq::fields));
+    GO(iseq).set(new_class(&quot;InstructionSequence&quot;, G(object), InstructionSequence::fields));
     G(iseq)-&gt;instance_type = Object::i2n(ISeqType);
 
     for(size_t i = 0; i &lt; SPECIAL_CLASS_SIZE; i += 4) {
@@ -202,7 +203,7 @@ namespace rubinius {
     Regexp::init(this);
 
     GO(cmethod_vis).set(new_class(&quot;CompiledMethod::Visibility&quot;, G(object),
-        CompiledMethod::Visibility::fields, G(cmethod)));
+        MethodVisibility::fields, G(cmethod)));
     G(cmethod_vis)-&gt;set_object_type(CMVisibilityType);
 
     Module* x = new_module(&quot;Rubinius&quot;);
@@ -219,6 +220,8 @@ namespace rubinius {
     init_ffi();
     Task::init(state);
     Thread::init(state);
+
+    TypeInfo::init(state);
   }
 
   void VM::bootstrap_symbol() {</diff>
      <filename>vm/objects.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -5,434 +5,105 @@
 #include &quot;object.hpp&quot;
 #include &quot;type_info.hpp&quot;
 
+#include &lt;iostream&gt;
+
 namespace rubinius {
   class BuiltinType : public Object {
 
   };
-
-  class NilClass : public BuiltinType { };
-  /* NOTE(t1):
-   * This looks scary, but it's pretty simple. We're specializing
-   * the kind_of when passed NilClass to just test using nil_p().
-   * This makes kind_of smarter, letting us use it everywhere for
-   * type checks. */
-  template &lt;&gt;
-    static bool kind_of&lt;NilClass&gt;(OBJECT obj) {
-      return obj == Qnil;
-    }
-
-  class TrueClass : public BuiltinType { };
-  /* See t1 */
-  template &lt;&gt;
-    static bool kind_of&lt;TrueClass&gt;(OBJECT obj) {
-      return obj == Qtrue;
-    }
-
-  class FalseClass : public BuiltinType { };
-  /* See t1 */
-  template &lt;&gt;
-    static bool kind_of&lt;FalseClass&gt;(OBJECT obj) {
-      return obj == Qfalse;
-    }
-  
-  class Integer : public BuiltinType {
-  public:
-    inline native_int n2i();
-  };
 }
 
-#include &quot;builtin_bignum.hpp&quot;
+#include &quot;builtin_immediates.hpp&quot;
 
 namespace rubinius {
-
-  class Fixnum : public Integer {
+  class Numeric : public BuiltinType {
   public:
-    const static size_t fields = 0;
-    const static object_type type = FixnumType;
-
-    INTEGER add(STATE, FIXNUM other) {
-      return Object::i2n(state, n2i() + other-&gt;n2i());
-    }
-
-    INTEGER sub(STATE, FIXNUM other) {
-      return Object::i2n(state, n2i() - other-&gt;n2i());
-    }
-
-    INTEGER multiply(STATE, FIXNUM other) {
-      return Object::i2n(state, n2i() * other-&gt;n2i());
-    }
-
-    INTEGER divide(STATE, FIXNUM other) {
-      return Object::i2n(state, n2i() / other-&gt;n2i());
-    }
+    static const object_type type = NumericType;
 
-    INTEGER modulo(STATE, FIXNUM other) {
-      return Object::i2n(state, n2i() % other-&gt;n2i());
-    }
-    
-    native_int to_nint() {
-      return STRIP_TAG(this);
-    }
-
-  };
-
-  typedef Fixnum* FIXNUM;
-
-  /* See t1 */
-  template &lt;&gt;
-    static bool kind_of&lt;Integer&gt;(OBJECT obj) {
-      return obj-&gt;fixnum_p() || (obj-&gt;reference_p() &amp;&amp; obj-&gt;obj_type == Bignum::type);
-    }
-
-  /* For some reason, the as&lt;&gt; template doesn't pick up the specialized kind_of&lt;&gt;, until
-   * we figure out why, just special as&lt;&gt; too. */
-  template &lt;&gt;
-    static INTEGER as&lt;Integer&gt;(OBJECT obj) {
-      if(kind_of&lt;Integer&gt;(obj)) return (Integer*)obj;
-      throw new TypeError(obj-&gt;obj_type, obj, &quot;can't be cast as an Integer&quot;);
-    }
-
-  template &lt;&gt;
-    static bool kind_of&lt;Fixnum&gt;(OBJECT obj) {
-      return obj-&gt;fixnum_p();
-    }
-  
-  class StaticScope : public BuiltinType {
+    class Info : public TypeInfo {
     public:
-    const static size_t fields = 3;
-    const static object_type type = StaticScopeType;
-
-    OBJECT instance_variables;
-    Module* module;
-    StaticScope* parent;
-
-    static StaticScope* create(STATE);
-  };
-
-  native_int Integer::n2i() {
-    if(fixnum_p()) {
-      return ((FIXNUM)this)-&gt;to_nint();
-    }
-
-    return as&lt;Bignum&gt;(this)-&gt;to_nint();
-  }
-
-};
-
-namespace rubinius {
-
-  class String;
-  class Hash;
-  class Tuple;
-
-  class Symbol : public BuiltinType {
-    public:
-    const static size_t fields = 0;
-    const static object_type type = SymbolType;
-
-    native_int index() {
-      return DATA_STRIP_TAG(this);
-    }
-
-    static Symbol* from_index(STATE, size_t index) {
-      return (Symbol*)DATA_APPLY_TAG(index, DATA_TAG_SYMBOL);
-    }
-
-    String* to_str(STATE);
+      Info(object_type type) : TypeInfo(type) { }
+    };
   };
 
-  /* See t1 */
-  template &lt;&gt;
-    static bool kind_of&lt;Symbol&gt;(OBJECT obj) {
-      return obj-&gt;symbol_p();
-    }
+  class Integer : public Numeric {
+  public:
+    static const object_type type = IntegerType;
 
-  typedef Symbol* SYMBOL;
+    inline native_int n2i();
 
-  class SymbolTable : public BuiltinType {
+    class Info : public TypeInfo {
     public:
-    const static size_t fields = 3;
-    const static object_type type = SymbolTableType;
-
-    OBJECT instance_variables;
-    Tuple* symbols;
-    Hash*  strings;
-
-    static SymbolTable* create(STATE);
-    SYMBOL lookup(STATE, const char* str, size_t size = 0);
-    SYMBOL lookup(STATE, String* str);
-    String* find_string(STATE, Symbol* sym);
+      Info(object_type type) : TypeInfo(type) { }
+    };
   };
-};
-
-namespace rubinius {
-  class Tuple : public BuiltinType {
-    public:
-    const static size_t fields = 0;
-    const static object_type type = TupleType;
+}
 
-    static Tuple* create(STATE, size_t fields);
-    static Tuple* from(STATE, size_t fields, ...);
-    static bool is_a(OBJECT obj) {
-      return obj-&gt;obj_type == TupleType;
-    }
+#include &quot;builtin_bignum.hpp&quot;
+#include &quot;builtin_fixnum.hpp&quot;
 
-    OBJECT put(STATE, size_t idx, OBJECT val);
-    void copy_from(STATE, Tuple* other, int start, int end);
+#include &quot;builtin_staticscope.hpp&quot;
+#include &quot;builtin_symbol.hpp&quot;
 
-  };
-};
+#include &quot;builtin_tuple.hpp&quot;
 
 #include &quot;builtin_hash.hpp&quot;
 
-
 namespace rubinius {
   class NormalObject : public BuiltinType {
-    public:
+  public:
     const static size_t fields = 1;
     const static object_type type = ObjectType;
 
     OBJECT instance_variables;
-  };
-};
-
-#include &quot;builtin_array.hpp&quot;
-
-namespace rubinius {
-  class Exception : public BuiltinType {
-    public:
-    const static size_t fields = 3;
-    const static object_type type = ExceptionType;
-
-    static Exception* create(STATE);
-    OBJECT instance_variables;
-    OBJECT message;
-    OBJECT context;
-  };
-};
-
-namespace rubinius {
-  class CompiledMethod;
-  class MethodContext;
-  class BlockContext;
-
-  class BlockEnvironment : public BuiltinType {
+    
+    class Info : public TypeInfo {
     public:
-    const static size_t fields = 5;
-    const static object_type type = BlockEnvType;
-
-    OBJECT instance_variables;
-    MethodContext* home;
-    MethodContext* home_block;
-    OBJECT local_count;
-    CompiledMethod* method;
-
-    static BlockEnvironment* under_context(STATE, CompiledMethod* cm,
-        MethodContext* parent, MethodContext* active);
-
-    void call(STATE, size_t args);
-    BlockContext* create_context(STATE);
+      Info(object_type type) : TypeInfo(type) { }
+    };
   };
 };
 
+#include &quot;builtin_array.hpp&quot;
+#include &quot;builtin_exception.hpp&quot;
 
-namespace rubinius {
-  class IO : public BuiltinType {
-    public:
-    const static size_t fields = 4;
-    const static object_type type = IOType;
-
-    OBJECT instance_variables;
-    OBJECT descriptor;
-    OBJECT buffer;
-    OBJECT mode;
-
-    static void init(STATE);
-    static IO* create(STATE, int fd);
-
-    class Buffer : public BuiltinType {
-    public:
-      const static size_t fields = 4;
-      const static object_type type = IOBufferType;
-
-      OBJECT instance_variables;
-      OBJECT storage;
-      INTEGER total;
-      INTEGER used;
-
-      static Buffer* create(STATE, size_t bytes);
-      void reset(STATE);
-      String* drain(STATE);
-
-      char* byte_address() {
-        return (char*)storage-&gt;bytes;
-      }
-
-      size_t left() {
-        return total-&gt;n2i() - used-&gt;n2i();
-      }
-
-      char* at_unused() {
-        char* start = (char*)storage-&gt;bytes;
-        start += used-&gt;n2i();
-        return start;
-      }
+#include &quot;builtin_block_environment.hpp&quot;
 
-      void read_bytes(size_t bytes) {
-        used = Object::i2n(used-&gt;n2i() + bytes);
-      }
-
-    };
-  };
-};
+#include &quot;builtin_io.hpp&quot;
 
 #include &quot;builtin_regexp.hpp&quot;
+#include &quot;builtin_bytearray.hpp&quot;
 #include &quot;builtin_string.hpp&quot;
 
-namespace rubinius {
-  class ByteArray : public BuiltinType {
-    public:
-    const static size_t fields = 0;
-    const static object_type type = ByteArrayType;
-
-    static ByteArray* create(STATE, size_t bytes);
-  };
-};
+#include &quot;builtin_lookuptable.hpp&quot;
+#include &quot;builtin_methodtable.hpp&quot;
 
-namespace rubinius {
-  #define LOOKUPTABLE_MIN_SIZE 16
-  class LookupTable : public BuiltinType {
-    public:
-    const static size_t fields = 4;
-    const static object_type type = LookupTableType;
-
-    OBJECT instance_variables;
-    Tuple* values;
-    INTEGER bins;
-    INTEGER entries;
-
-    /* Prototypes */
-    static LookupTable* create(STATE, size_t sz = LOOKUPTABLE_MIN_SIZE);
-    void setup(STATE, size_t sz);
-    OBJECT store(STATE, OBJECT key, OBJECT val);
-    OBJECT fetch(STATE, OBJECT key);
-    OBJECT fetch(STATE, OBJECT key, bool* found);
-    LookupTable* dup(STATE);
-    static OBJECT entry_new(STATE, OBJECT key, OBJECT val);
-    static OBJECT entry_append(STATE, OBJECT top, OBJECT nxt);
-    void   redistribute(STATE, size_t size);
-    OBJECT find_entry(STATE, OBJECT key);
-    OBJECT find(STATE, OBJECT key);
-    OBJECT remove(STATE, OBJECT key);
-    OBJECT has_key(STATE, OBJECT key);
-    static Array* collect(STATE, LookupTable* tbl, OBJECT (*action)(STATE, OBJECT));
-    static OBJECT get_key(STATE, OBJECT entry);
-    Array* all_keys(STATE);
-    static OBJECT get_value(STATE, OBJECT entry);
-    Array* all_values(STATE);
-    static OBJECT get_entry(STATE, OBJECT entry);
-    OBJECT all_entries(STATE);
-  };
-
-  class MethodTable : public LookupTable {
-    public:
-    const static object_type type = MTType;
-    static MethodTable* create(STATE);
-  };
-};
-
-namespace rubinius {
-
-  class Executable : public BuiltinType {
-    public:
-    const static size_t fields = 4;
-    const static object_type type = ExecutableType;
-
-    OBJECT instance_variables;
-    OBJECT primitive;
-    OBJECT required;
-    OBJECT serial;
-  };
-
-
-  class ISeq;
-  class MemoryPointer;
-  class VMMethod;
-
-  class CompiledMethod : public Executable {
-    public:
-    const static size_t fields = 20;
-    const static object_type type = CMethodType;
-    const static size_t saved_fields = 16;
-
-    SYMBOL name;
-    ISeq*  iseq;
-    FIXNUM stack_size;
-    FIXNUM local_count;
-    FIXNUM required_args;
-    FIXNUM total_args;
-    OBJECT splat;
-    Tuple* literals;
-    Tuple* exceptions;
-    Tuple* lines;
-    SYMBOL file;
-    SYMBOL path;
-    FIXNUM serial;
-    OBJECT bonus;
-    MemoryPointer* compiled;
-    StaticScope* scope;
-
-    static CompiledMethod* create(STATE);
-    void post_marshal(STATE);
-    size_t number_of_locals();
-    void set_scope(StaticScope*);
-    VMMethod* vmmethod(STATE);
-
-    class Visibility : public BuiltinType {
-    public:
-      const static size_t fields = 3;
-      const static object_type type = CMVisibilityType;
-
-      LookupTable* instance_variables;
-      SYMBOL visibility;
-      Executable* method;
-
-      static Visibility* create(STATE);
-
-      bool public_p(STATE) {
-        return visibility == G(sym_public);
-      }
-
-      bool private_p(STATE) {
-        return visibility == G(sym_private);
-      }
-
-      bool protected_p(STATE) {
-        return visibility == G(sym_protected);
-      }
-    };
-  };
-
-  template &lt;&gt;
-    static bool kind_of&lt;Executable&gt;(OBJECT obj) {
-      if(obj-&gt;obj_type == Executable::type ||
-         obj-&gt;obj_type == CompiledMethod::type) {
-        return true;
-      }
-
-      return false;
-    }
-};
+#include &quot;builtin_executable.hpp&quot;
 
+#include &quot;builtin_compiledmethod.hpp&quot;
 
 #include &quot;builtin_class.hpp&quot;
 #include &quot;builtin_contexts.hpp&quot;
 #include &quot;builtin_iseq.hpp&quot;
 #include &quot;builtin_float.hpp&quot;
+
+namespace rubinius {
+  template &lt;&gt;
+    static bool kind_of&lt;Numeric&gt;(OBJECT obj) {
+      return obj-&gt;fixnum_p() || 
+        (obj-&gt;reference_p() &amp;&amp; (
+          obj-&gt;obj_type == Bignum::type ||
+          obj-&gt;obj_type == Float::type));
+    }
+}
+  
 #include &quot;builtin_list.hpp&quot;
 #include &quot;builtin_selector.hpp&quot;
 #include &quot;builtin_task.hpp&quot;
 #include &quot;builtin_iseq.hpp&quot;
 #include &quot;builtin_channel.hpp&quot;
 
+#include &quot;builtin_memorypointer.hpp&quot;
+#include &quot;builtin_nativefunction.hpp&quot;
+
 #endif</diff>
      <filename>vm/objects.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -11,6 +11,10 @@
 #define G(whatever) state-&gt;globals.whatever.get()
 #define GO(whatever) state-&gt;globals.whatever
 
+/* a noop identifier which goes in front of all declared typed slots.
+ * This aids in finding them via parsing */
+#define gc
+
 namespace rubinius {
   typedef intptr_t native_int;
 </diff>
      <filename>vm/prelude.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -10,6 +10,8 @@ class CCompile
     @flags = []
     @linker = &quot;gcc&quot;
     @deps = {}
+
+    Dir.mkdir &quot;.deps&quot; unless File.directory?(&quot;.deps&quot;)
   end
 
   attr_accessor :includes, :flags, :deps
@@ -43,7 +45,19 @@ class CCompile
     objects = []
 
     list.each do |name|
-      headers = extract_headers(name)
+      next if name == &quot;../main.cpp&quot;
+      deps = File.join(&quot;.deps&quot;, name.hash.to_s)
+      if File.exists?(deps) and File.mtime(deps) &gt; File.mtime(name)
+        headers = Marshal.load(File.read(deps)) rescue nil
+      else
+        headers = nil
+      end
+
+      unless headers
+        puts &quot;DEP #{name}&quot;
+        headers = extract_headers(name)
+        File.open(deps, &quot;w&quot;) { |f| f &lt;&lt; Marshal.dump(headers) }
+      end
 
       output = name.gsub(/\.[^.]+$/, &quot;.o&quot;)
       objects &lt;&lt; output
@@ -57,6 +71,15 @@ class CCompile
   end
 
   def extract_headers(path)
+    includes = @includes.map { |i| &quot;-I#{i}&quot; }.join(&quot; &quot;)
+    data = `g++ #{includes} -MM -c #{path}`.split(/(?:\s+|\\\n)/)
+    data.shift
+    data.reject! { |s| s.size == 0 }
+
+    return data
+  end
+
+  def ruby_extract_headers(path)
     dir = File.dirname(path)
     h = File.read(path).scan(/#include\s*.([^\n]*)./).map do |i|
       File.join(dir, i[0])
@@ -131,7 +154,17 @@ file &quot;../gen/task_instructions_switch.c&quot; =&gt; &quot;../instructions.rb&quot; do
   x &quot;cd ..; ruby instructions.rb&quot;
 end
 
+file &quot;../gen/primitive_implementation.gen.cpp&quot; =&gt; &quot;../primitives.rb&quot; do
+  puts &quot;GEN primitives.rb&quot;
+  x &quot;cd ..; ruby primitives.rb&quot;
+end
+
 file &quot;../builtin_task.o&quot; =&gt; &quot;../gen/task_instructions_switch.c&quot;
+file &quot;../primitives.o&quot; =&gt; &quot;../gen/primitive_implementation.gen.cpp&quot;
+file &quot;../type_info.o&quot; =&gt; &quot;../gen/typechecks.gen.cpp&quot;
+file &quot;../gen/typechecks.gen.cpp&quot; =&gt; FileList[&quot;../builtin_*.hpp&quot;] do
+  Rake::Task[:field_extract].invoke
+end
 
 file &quot;runner.cpp&quot; =&gt; tests + objs do
   puts &quot;GEN runner.cpp&quot;
@@ -146,10 +179,31 @@ file &quot;runner&quot; =&gt; &quot;runner.o&quot; do
   compiler.link &quot;runner&quot;, :objects =&gt; objs + [&quot;runner.o&quot;], :libs =&gt; ex_libs
 end
 
+file &quot;../main.o&quot; =&gt; &quot;../main.cpp&quot; do
+  compiler.compile &quot;../main.cpp&quot;
+end
+
+file &quot;../vm&quot; =&gt; objs + [&quot;../main.o&quot;] do
+  puts &quot;LD ../vm&quot;
+  compiler.link &quot;../vm&quot;, :objects =&gt; objs + [&quot;../main.o&quot;], :libs =&gt; ex_libs
+end
+
 task :test =&gt; &quot;runner&quot; do
   x &quot;./runner&quot;
 end
 
+task :field_extract do
+  order = [&quot;objects.hpp&quot;]
+  File.open(&quot;../objects.hpp&quot;) do |f|
+    f.each_line do |line|
+      if /\#include &quot;builtin_(.*)&quot;/.match(line)
+        order &lt;&lt; &quot;builtin_#{$1}&quot;
+      end
+    end
+  end
+  sh &quot;cd ..; ruby field_extract.rb #{order.join(' ')}&quot;
+end
+
 simple = objs + (compiler &lt;&lt; &quot;simple.cpp&quot;)
 
 task :simple =&gt; simple do</diff>
      <filename>vm/test/Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -2,6 +2,7 @@
 #include &quot;builtin_list.hpp&quot;
 #include &quot;vm.hpp&quot;
 #include &quot;objectmemory.hpp&quot;
+#include &quot;event.hpp&quot;
 
 #include &lt;cxxtest/TestSuite.h&gt;
 
@@ -69,13 +70,65 @@ class TestChannel : public CxxTest::TestSuite {
 
   void test_receive_causes_thread_switch() {
     Thread* other = Thread::create(state);
-    Thread* waiter = Thread::create(state);
 
+    Thread* orig = G(current_thread);
+
+    G(current_task)-&gt;stack = Tuple::create(state, 10);
     state-&gt;queue_thread(other);
-    state-&gt;activate_thread(waiter);
-    TS_ASSERT_EQUALS(G(current_thread), waiter);
 
+    chan-&gt;receive(state);
+    TS_ASSERT_EQUALS(G(current_thread), other);
+    TS_ASSERT_EQUALS(orig-&gt;get_ivar(state, state-&gt;symbol(&quot;@sleep&quot;)), Qtrue);
+  }
+
+  void test_receive_causes_event_block() {
+    ChannelCallback cb(state, chan);
+    event::Timer* timer = new event::Timer(state, &amp;cb, 0.2);
+
+    Thread* orig = G(current_thread);
+    state-&gt;events-&gt;start(timer);
+
+    G(current_task)-&gt;stack = Tuple::create(state, 10);
+
+    TS_ASSERT(!state-&gt;wait_events);
+    chan-&gt;receive(state);
+
+    TS_ASSERT_EQUALS(chan-&gt;waiting-&gt;locate(state, 0), G(current_thread));
+
+    TS_ASSERT(state-&gt;wait_events);
+    state-&gt;events-&gt;run_and_wait();
 
+    TS_ASSERT(chan-&gt;waiting-&gt;empty_p());
+
+    TS_ASSERT_EQUALS(G(current_thread), orig);
+    TS_ASSERT_EQUALS(G(current_task)-&gt;sp, 0);
+    TS_ASSERT_EQUALS(G(current_task)-&gt;stack-&gt;at(0), Qnil)
+  }
+
+  void test_receive_polls_events() {
+    ChannelCallback cb(state, chan);
+    event::Timer* timer = new event::Timer(state, &amp;cb, 0.2);
+
+    Thread* orig = G(current_thread);
+    state-&gt;events-&gt;start(timer);
+
+    G(current_task)-&gt;stack = Tuple::create(state, 10);
+
+    TS_ASSERT(!state-&gt;wait_events);
+    usleep(300000);
+    chan-&gt;receive(state);
+    TS_ASSERT(!state-&gt;wait_events);
+    
+    TS_ASSERT(chan-&gt;waiting-&gt;empty_p());
+
+    TS_ASSERT_EQUALS(G(current_thread), orig);
+    TS_ASSERT_EQUALS(G(current_task)-&gt;sp, 0);
+    TS_ASSERT_EQUALS(G(current_task)-&gt;stack-&gt;at(0), Qnil)
+  }
 
+  void test_has_readers_p() {
+    TS_ASSERT(!chan-&gt;has_readers_p());
+    chan-&gt;waiting-&gt;append(state, G(current_thread));
+    TS_ASSERT(chan-&gt;has_readers_p());
   }
 };</diff>
      <filename>vm/test/test_channel.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -78,7 +78,7 @@ class TestEventLoop : public CxxTest::TestSuite {
     TestChannelObject chan(state);
     event::Read* read = new event::Read(state, &amp;chan, fds[0]);
     
-    IO::Buffer *buf = IO::Buffer::create(state, 12);
+    IOBuffer *buf = IOBuffer::create(state, 12);
     read-&gt;into_buffer(buf, 1);
     TS_ASSERT_EQUALS(buf-&gt;used, Object::i2n(0));
 </diff>
      <filename>vm/test/test_event.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -16,6 +16,7 @@ class TestLookupTable : public CxxTest::TestSuite {
 
     tbl = LookupTable::create(&amp;vm);
     TS_ASSERT_EQUALS(tbl-&gt;obj_type, LookupTableType);
+    TS_ASSERT_EQUALS(tbl-&gt;bins-&gt;n2i(), LOOKUPTABLE_MIN_SIZE);
   }
 
   void test_store_fetch() {
@@ -67,11 +68,11 @@ class TestLookupTable : public CxxTest::TestSuite {
     tbl-&gt;store(state, k3, v3);
     TS_ASSERT_EQUALS(as&lt;Integer&gt;(tbl-&gt;entries)-&gt;n2i(), 3);
 
-    OBJECT entry = tbl-&gt;find_entry(state, k1);
-    TS_ASSERT(!entry-&gt;nil_p());
+    Tuple* entry = tbl-&gt;find_entry(state, k1);
+    TS_ASSERT(entry);
 
     TS_ASSERT(!entry-&gt;at(2)-&gt;nil_p());
-    TS_ASSERT_EQUALS(entry-&gt;at(2)-&gt;at(0), k2);
+    TS_ASSERT_EQUALS(as&lt;Tuple&gt;(entry-&gt;at(2))-&gt;at(0), k2);
 
     entry = tbl-&gt;find_entry(state, k3);
     TS_ASSERT(!entry-&gt;nil_p());
@@ -128,11 +129,11 @@ class TestLookupTable : public CxxTest::TestSuite {
     OBJECT k = Object::i2n(47);
     tbl-&gt;store(state, k, Qtrue);
 
-    OBJECT entry = tbl-&gt;find_entry(state, k);
+    Tuple* entry = tbl-&gt;find_entry(state, k);
     TS_ASSERT_EQUALS(k, entry-&gt;at(0));
 
     entry = tbl-&gt;find_entry(state, Object::i2n(40));
-    TS_ASSERT(entry-&gt;nil_p());
+    TS_ASSERT(!entry);
   }
 
   void test_find() {</diff>
      <filename>vm/test/test_lookuptable.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -54,12 +54,12 @@ public:
 
   void test_symbol() {
     mar-&gt;marshal(state-&gt;symbol(&quot;blah&quot;));
-    TS_ASSERT_EQUALS(mar-&gt;sstream.str(), &quot;x\nblah\n&quot;);
+    TS_ASSERT_EQUALS(mar-&gt;sstream.str(), &quot;x\n4\nblah\n&quot;);
   }
 
   void test_sendsite() {
     mar-&gt;marshal(SendSite::create(state, state-&gt;symbol(&quot;blah&quot;)));
-    TS_ASSERT_EQUALS(mar-&gt;sstream.str(), &quot;S\nblah\n&quot;);
+    TS_ASSERT_EQUALS(mar-&gt;sstream.str(), &quot;S\n4\nblah\n&quot;);
   }
 
   void test_array() {
@@ -98,4 +98,12 @@ public:
     TS_ASSERT_EQUALS(mar-&gt;sstream.str(), std::string(&quot;d\n15.5\n&quot;));
   }
 
+  void test_iseq() {
+    InstructionSequence* iseq = InstructionSequence::create(state, 1);
+    iseq-&gt;opcodes-&gt;put(state, 0, Object::i2n(0));
+
+    mar-&gt;marshal(iseq);
+    TS_ASSERT_EQUALS(mar-&gt;sstream.str(), std::string(&quot;i\n1\n0\n&quot;));
+  }
+
 };</diff>
      <filename>vm/test/test_marshal.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -35,7 +35,7 @@ class TestMessage : public CxxTest::TestSuite {
 
   CompiledMethod* create_cm() {
     CompiledMethod* cm = CompiledMethod::create(state);
-    cm-&gt;iseq = ISeq::create(state, 40);
+    cm-&gt;iseq = InstructionSequence::create(state, 40);
     cm-&gt;stack_size = Object::i2n(10);
     cm-&gt;total_args = Object::i2n(0);
     cm-&gt;required_args = cm-&gt;total_args;</diff>
      <filename>vm/test/test_message.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -68,16 +68,16 @@ class TestObject : public CxxTest::TestSuite {
   }
 
   void test_metaclass() {
-    TS_ASSERT(MetaClass::is_a(G(object)-&gt;metaclass(state)));
+    TS_ASSERT(kind_of&lt;MetaClass&gt;(G(object)-&gt;metaclass(state)));
     TS_ASSERT_EQUALS(Qnil-&gt;metaclass(state), G(nil_class));
     TS_ASSERT_EQUALS(Qtrue-&gt;metaclass(state), G(true_class));
     TS_ASSERT_EQUALS(Qfalse-&gt;metaclass(state), G(false_class));
 
     Tuple *tup = Tuple::create(state, 1);
-    TS_ASSERT(!MetaClass::is_a(tup-&gt;klass));
+    TS_ASSERT(!kind_of&lt;MetaClass&gt;(tup-&gt;klass));
 
-    TS_ASSERT(MetaClass::is_a(tup-&gt;metaclass(state)));
-    TS_ASSERT(MetaClass::is_a(tup-&gt;klass));
+    TS_ASSERT(kind_of&lt;MetaClass&gt;(tup-&gt;metaclass(state)));
+    TS_ASSERT(kind_of&lt;MetaClass&gt;(tup-&gt;klass));
   }
 
   void test_get_ivar() {</diff>
      <filename>vm/test/test_object.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -112,10 +112,10 @@ class TestObjectMemory : public CxxTest::TestSuite {
     obj = new_obj;
 
     TS_ASSERT(om.young.current-&gt;contains_p(obj));
-    obj3 = obj-&gt;at(0);
+    obj3 = obj-&gt;field[0];
     TS_ASSERT(obj2 != obj3);
 
-    TS_ASSERT_EQUALS(obj2-&gt;at(0), Qtrue);
+    TS_ASSERT_EQUALS(obj2-&gt;field[0], Qtrue);
   }
 
   /* Could crash on failure */
@@ -202,8 +202,8 @@ class TestObjectMemory : public CxxTest::TestSuite {
     Roots roots(0);
     om.collect_young(roots);
 
-    TS_ASSERT(mature-&gt;at(0) != young);
-    TS_ASSERT_EQUALS(mature-&gt;at(0)-&gt;at(0), Qtrue);
+    TS_ASSERT(mature-&gt;field[0] != young);
+    TS_ASSERT_EQUALS(mature-&gt;field[0]-&gt;field[0], Qtrue);
   }
 
   void test_collect_young_promotes_objects() {
@@ -249,7 +249,7 @@ class TestObjectMemory : public CxxTest::TestSuite {
 
     TS_ASSERT_EQUALS(young-&gt;age, 0);
     om.collect_young(roots);
-    TS_ASSERT_EQUALS(mature-&gt;at(0)-&gt;age, 1);
+    TS_ASSERT_EQUALS(mature-&gt;field[0]-&gt;age, 1);
     om.collect_young(roots);
 
     TS_ASSERT_EQUALS(om.remember_set-&gt;size(), 0);
@@ -273,9 +273,9 @@ class TestObjectMemory : public CxxTest::TestSuite {
 
     obj = roots.front()-&gt;get();
 
-    obj2 = obj-&gt;at(0);
-    TS_ASSERT_EQUALS(obj2, obj-&gt;at(1));
-    TS_ASSERT_EQUALS(obj2, obj-&gt;at(2));
+    obj2 = obj-&gt;field[0];
+    TS_ASSERT_EQUALS(obj2, obj-&gt;field[1]);
+    TS_ASSERT_EQUALS(obj2, obj-&gt;field[2]);
   }
 
   void test_collect_young_copies_byte_bodies() {
@@ -376,9 +376,9 @@ class TestObjectMemory : public CxxTest::TestSuite {
     om.collect_mature(roots);
 
     young = roots.front()-&gt;get();
-    mature = young-&gt;at(0);
+    mature = young-&gt;field[0];
 
-    TS_ASSERT_EQUALS(mature-&gt;at(0), young);
+    TS_ASSERT_EQUALS(mature-&gt;field[0], young);
   }
 
   void test_collect_young_stops_at_already_marked_objects() {
@@ -399,10 +399,10 @@ class TestObjectMemory : public CxxTest::TestSuite {
     om.collect_young(roots);
 
     obj = roots.front()-&gt;get();
-    obj2 = obj-&gt;at(0);
+    obj2 = obj-&gt;field[0];
 
-    TS_ASSERT_EQUALS(obj2-&gt;at(0), obj);
-    TS_ASSERT_EQUALS(obj2-&gt;at(1), Qtrue);
+    TS_ASSERT_EQUALS(obj2-&gt;field[0], obj);
+    TS_ASSERT_EQUALS(obj2-&gt;field[1], Qtrue);
   }
 
   void test_collect_young_tells_objectmemory_about_collection() {</diff>
      <filename>vm/test/test_objectmemory.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -30,8 +30,9 @@ class TestObjects : public CxxTest::TestSuite {
   void test_class() {
     Class *cls;
 
-    cls = (Class*)G(klass);
-    TS_ASSERT_EQUALS(cls-&gt;class_object(state), cls);
+    cls = G(klass);
+    Class* o = cls-&gt;class_object(state);
+    TS_ASSERT_EQUALS(cls, o);
     TS_ASSERT_EQUALS(cls-&gt;superclass, G(module));
     check_const(klass, &quot;Class&quot;);
   }
@@ -42,7 +43,7 @@ class TestObjects : public CxxTest::TestSuite {
 
     cls = (Class*)G(klass);
     meta = (MetaClass*)cls-&gt;klass;
-    TS_ASSERT(MetaClass::is_a(G(object)-&gt;klass));
+    TS_ASSERT(kind_of&lt;MetaClass&gt;(G(object)-&gt;klass));
     TS_ASSERT(kind_of&lt;LookupTable&gt;(meta-&gt;method_table));
     TS_ASSERT(kind_of&lt;LookupTable&gt;(meta-&gt;constants));
   }</diff>
      <filename>vm/test/test_objects.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -89,7 +89,7 @@ class TestRegexp : public CxxTest::TestSuite {
     TS_ASSERT_EQUALS(as&lt;Integer&gt;(matches-&gt;full-&gt;at(1))-&gt;n2i(), 2);
     
     TS_ASSERT_EQUALS(matches-&gt;region-&gt;field_count, 1);
-    TS_ASSERT_EQUALS(as&lt;Integer&gt;(matches-&gt;region-&gt;at(0)-&gt;at(0))-&gt;n2i(), 1);
-    TS_ASSERT_EQUALS(as&lt;Integer&gt;(matches-&gt;region-&gt;at(0)-&gt;at(1))-&gt;n2i(), 2);
+    TS_ASSERT_EQUALS(as&lt;Integer&gt;(as&lt;Tuple&gt;(matches-&gt;region-&gt;at(0))-&gt;at(0))-&gt;n2i(), 1);
+    TS_ASSERT_EQUALS(as&lt;Integer&gt;(as&lt;Tuple&gt;(matches-&gt;region-&gt;at(0))-&gt;at(1))-&gt;n2i(), 2);
   }
 };</diff>
      <filename>vm/test/test_regexp.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -23,7 +23,7 @@ class TestTask : public CxxTest::TestSuite {
 
   CompiledMethod* create_cm() {
     CompiledMethod* cm = CompiledMethod::create(state);
-    cm-&gt;iseq = ISeq::create(state, 40);
+    cm-&gt;iseq = InstructionSequence::create(state, 40);
     cm-&gt;stack_size = Object::i2n(10);
     cm-&gt;total_args = Object::i2n(0);
     cm-&gt;required_args = cm-&gt;total_args;
@@ -456,7 +456,7 @@ class TestTask : public CxxTest::TestSuite {
 
     Task* task = Task::create(state, Qnil, cm);
 
-    CompiledMethod::Visibility* vis = CompiledMethod::Visibility::create(state);
+    MethodVisibility* vis = MethodVisibility::create(state);
     vis-&gt;method = cm;
     vis-&gt;visibility = G(sym_private);
 
@@ -473,7 +473,7 @@ class TestTask : public CxxTest::TestSuite {
 
     Task* task = Task::create(state, Qnil, cm);
 
-    CompiledMethod::Visibility* vis = CompiledMethod::Visibility::create(state);
+    MethodVisibility* vis = MethodVisibility::create(state);
     vis-&gt;method = cm;
     vis-&gt;visibility = G(sym_private);
 
@@ -571,7 +571,7 @@ class TestTask : public CxxTest::TestSuite {
     SET(cs, parent, ps);
 
     CompiledMethod* cm = CompiledMethod::create(state);
-    cm-&gt;iseq = ISeq::create(state, 40);
+    cm-&gt;iseq = InstructionSequence::create(state, 40);
     cm-&gt;stack_size = Object::i2n(1);
 
     Task* task = Task::create(state, Qnil, cm);
@@ -612,7 +612,7 @@ class TestTask : public CxxTest::TestSuite {
     SET(child, superclass, inc);
 
     CompiledMethod* cm = CompiledMethod::create(state);
-    cm-&gt;iseq = ISeq::create(state, 40);
+    cm-&gt;iseq = InstructionSequence::create(state, 40);
     cm-&gt;stack_size = Object::i2n(1);
 
     Task* task = Task::create(state, Qnil, cm);
@@ -641,7 +641,7 @@ class TestTask : public CxxTest::TestSuite {
     G(object)-&gt;set_const(state, &quot;Age&quot;, Object::i2n(28));
 
     CompiledMethod* cm = CompiledMethod::create(state);
-    cm-&gt;iseq = ISeq::create(state, 40);
+    cm-&gt;iseq = InstructionSequence::create(state, 40);
     cm-&gt;stack_size = Object::i2n(1);
 
     Task* task = Task::create(state, Qnil, cm);
@@ -662,7 +662,7 @@ class TestTask : public CxxTest::TestSuite {
     ps-&gt;parent = (StaticScope*)Qnil;
 
     CompiledMethod* cm = CompiledMethod::create(state);
-    cm-&gt;iseq = ISeq::create(state, 40);
+    cm-&gt;iseq = InstructionSequence::create(state, 40);
     cm-&gt;stack_size = Object::i2n(1);
 
     Task* task = Task::create(state, Qnil, cm);
@@ -681,7 +681,7 @@ class TestTask : public CxxTest::TestSuite {
     ps-&gt;parent = (StaticScope*)Qnil;
 
     CompiledMethod* cm = CompiledMethod::create(state);
-    cm-&gt;iseq = ISeq::create(state, 40);
+    cm-&gt;iseq = InstructionSequence::create(state, 40);
     cm-&gt;stack_size = Object::i2n(1);
 
     Task* task = Task::create(state, Qnil, cm);
@@ -701,7 +701,7 @@ class TestTask : public CxxTest::TestSuite {
       thrown = true;
     }
 
-    TS_ASSERT(thrown);
+    TS_ASSERT(!thrown);
   }
 
   void test_current_module() {
@@ -712,7 +712,7 @@ class TestTask : public CxxTest::TestSuite {
     ps-&gt;parent = (StaticScope*)Qnil;
 
     CompiledMethod* cm = CompiledMethod::create(state);
-    cm-&gt;iseq = ISeq::create(state, 40);
+    cm-&gt;iseq = InstructionSequence::create(state, 40);
     cm-&gt;stack_size = Object::i2n(1);
 
     Task* task = Task::create(state, Qnil, cm);
@@ -729,7 +729,7 @@ class TestTask : public CxxTest::TestSuite {
     ps-&gt;parent = (StaticScope*)Qnil;
 
     CompiledMethod* cm = CompiledMethod::create(state);
-    cm-&gt;iseq = ISeq::create(state, 40);
+    cm-&gt;iseq = InstructionSequence::create(state, 40);
     cm-&gt;stack_size = Object::i2n(1);
 
     Task* task = Task::create(state, Qnil, cm);
@@ -752,7 +752,7 @@ class TestTask : public CxxTest::TestSuite {
     ps-&gt;parent = (StaticScope*)Qnil;
 
     CompiledMethod* cm = CompiledMethod::create(state);
-    cm-&gt;iseq = ISeq::create(state, 40);
+    cm-&gt;iseq = InstructionSequence::create(state, 40);
     cm-&gt;stack_size = Object::i2n(1);
 
     Task* task = Task::create(state, Qnil, cm);
@@ -775,7 +775,7 @@ class TestTask : public CxxTest::TestSuite {
     ps-&gt;parent = (StaticScope*)Qnil;
 
     CompiledMethod* cm = CompiledMethod::create(state);
-    cm-&gt;iseq = ISeq::create(state, 40);
+    cm-&gt;iseq = InstructionSequence::create(state, 40);
     cm-&gt;stack_size = Object::i2n(1);
 
     Task* task = Task::create(state, Qnil, cm);
@@ -796,7 +796,7 @@ class TestTask : public CxxTest::TestSuite {
     ps-&gt;parent = (StaticScope*)Qnil;
 
     CompiledMethod* cm = CompiledMethod::create(state);
-    cm-&gt;iseq = ISeq::create(state, 40);
+    cm-&gt;iseq = InstructionSequence::create(state, 40);
     cm-&gt;stack_size = Object::i2n(1);
 
     Task* task = Task::create(state, Qnil, cm);
@@ -811,7 +811,7 @@ class TestTask : public CxxTest::TestSuite {
 
   void test_raise_exception() {
     CompiledMethod* cm = CompiledMethod::create(state);
-    cm-&gt;iseq = ISeq::create(state, 40);
+    cm-&gt;iseq = InstructionSequence::create(state, 40);
     cm-&gt;total_args = Object::i2n(0);
     cm-&gt;stack_size = Object::i2n(1);
     cm-&gt;exceptions = Tuple::from(state, 1,
@@ -847,7 +847,7 @@ class TestTask : public CxxTest::TestSuite {
 
   void test_raise_exception_into_sender() {
     CompiledMethod* cm = CompiledMethod::create(state);
-    cm-&gt;iseq = ISeq::create(state, 40);
+    cm-&gt;iseq = InstructionSequence::create(state, 40);
     cm-&gt;stack_size = Object::i2n(1);
     cm-&gt;exceptions = Tuple::from(state, 1,
         Tuple::from(state, 3, Object::i2n(0), Object::i2n(3), Object::i2n(5)));</diff>
      <filename>vm/test/test_task.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -5,6 +5,8 @@
 #include &lt;iostream&gt;
 #include &lt;sstream&gt;
 
+
+
 using namespace rubinius;
 
 class StringUnMarshaller : public UnMarshaller {
@@ -30,6 +32,23 @@ public:
     delete mar;
   }
 
+  bool tuple_equals(Tuple* x, Tuple* y) {
+    if(x-&gt;field_count != y-&gt;field_count) return false;
+    for(size_t i = 0; i &lt; x-&gt;field_count; i++) {
+      OBJECT x1 = x-&gt;at(i);
+      OBJECT y1 = y-&gt;at(i);
+
+      if(kind_of&lt;Tuple&gt;(x1)) {
+        if(!tuple_equals(as&lt;Tuple&gt;(x1), as&lt;Tuple&gt;(y1))) return false;
+      } else {
+        if(x1 != y1) return false;
+      }
+    }
+
+    return true;
+  }
+
+
   void test_init() {
     mar-&gt;sstream.str(std::string(&quot;I\n3\n&quot;));
     OBJECT obj = mar-&gt;unmarshal();
@@ -48,7 +67,7 @@ public:
   }
 
   void test_symbol() {
-    mar-&gt;sstream.str(std::string(&quot;x\nblah\n&quot;));
+    mar-&gt;sstream.str(std::string(&quot;x\n4\nblah\n&quot;));
     OBJECT obj = mar-&gt;unmarshal();
 
     TS_ASSERT(obj-&gt;symbol_p());
@@ -56,15 +75,16 @@ public:
   }
   
   void test_sendsite() {
-    mar-&gt;sstream.str(std::string(&quot;S\nblah\n&quot;));
+    mar-&gt;sstream.str(std::string(&quot;S\n4\nblah\n&quot;));
     OBJECT obj = mar-&gt;unmarshal();
 
     TS_ASSERT(kind_of&lt;SendSite&gt;(obj));
+
     TS_ASSERT_EQUALS(as&lt;SendSite&gt;(obj)-&gt;name, state-&gt;symbol(&quot;blah&quot;));
   }
 
   void test_array() {
-    mar-&gt;sstream.str(std::string(&quot;A\n3\nI\n1\nx\nfoo\ns\n3\nblah\n&quot;));
+    mar-&gt;sstream.str(std::string(&quot;A\n3\nI\n1\nx\n3\nfoo\ns\n4\nblah\n&quot;));
     OBJECT obj = mar-&gt;unmarshal();
 
     TS_ASSERT(kind_of&lt;Array&gt;(obj));
@@ -103,4 +123,48 @@ public:
     TS_ASSERT_EQUALS(flt-&gt;val, 15.5);
   }
 
+  void test_iseq() {
+    mar-&gt;sstream.str(std::string(&quot;i\n1\n0\n&quot;));
+
+    OBJECT obj = mar-&gt;unmarshal();
+
+    TS_ASSERT(kind_of&lt;InstructionSequence&gt;(obj));
+
+    InstructionSequence* seq = as&lt;InstructionSequence&gt;(obj);
+
+    TS_ASSERT(kind_of&lt;Tuple&gt;(seq-&gt;opcodes));
+
+    TS_ASSERT_EQUALS(seq-&gt;opcodes-&gt;field_count, 1);
+
+    TS_ASSERT_EQUALS(seq-&gt;opcodes-&gt;at(0), Object::i2n(0));
+  }
+
+  void test_cmethod() {
+    std::string str = &quot;M\n1\nn\nx\n4\nblah\nx\n4\ntest\ni\n1\n0\nI\n10\nI\n0\nI\n0\nI\n0\nn\np\n2\nI\n1\nI\n2\nn\np\n1\np\n3\nI\n0\nI\n1\nI\n1\nx\n8\nnot_real\np\n1\nx\n4\nblah\n&quot;;
+    mar-&gt;sstream.str(str);
+
+    OBJECT obj = mar-&gt;unmarshal();
+
+    TS_ASSERT(kind_of&lt;CompiledMethod&gt;(obj));
+
+    CompiledMethod* cm = as&lt;CompiledMethod&gt;(obj);
+
+    TS_ASSERT_EQUALS(cm-&gt;__ivars__, Qnil);
+    TS_ASSERT_EQUALS(cm-&gt;primitive, state-&gt;symbol(&quot;blah&quot;));
+    TS_ASSERT_EQUALS(cm-&gt;name, state-&gt;symbol(&quot;test&quot;));
+    TS_ASSERT(tuple_equals(cm-&gt;iseq-&gt;opcodes, Tuple::from(state, 1, Object::i2n(0))));
+    TS_ASSERT_EQUALS(cm-&gt;stack_size, Object::i2n(10));
+    TS_ASSERT_EQUALS(cm-&gt;local_count, Object::i2n(0));
+    TS_ASSERT_EQUALS(cm-&gt;required_args, Object::i2n(0));
+    TS_ASSERT_EQUALS(cm-&gt;total_args, Object::i2n(0));
+    TS_ASSERT_EQUALS(cm-&gt;splat, Qnil);
+    TS_ASSERT(tuple_equals(cm-&gt;literals, Tuple::from(state, 2, Object::i2n(1), Object::i2n(2))));
+    TS_ASSERT_EQUALS(cm-&gt;exceptions, Qnil);
+    TS_ASSERT(tuple_equals(cm-&gt;lines, Tuple::from(state, 1, 
+          Tuple::from(state, 3, Object::i2n(0), Object::i2n(1), Object::i2n(1)))));
+
+    TS_ASSERT_EQUALS(cm-&gt;file, state-&gt;symbol(&quot;not_real&quot;));
+    TS_ASSERT(tuple_equals(cm-&gt;local_names, Tuple::from(state, 1, state-&gt;symbol(&quot;blah&quot;))));
+  }
+
 };</diff>
      <filename>vm/test/test_unmarshal.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -13,7 +13,7 @@ class TestVM : public CxxTest::TestSuite {
   VM *state;
 
   void setUp() {
-    state = new VM(1024);
+    state = new VM();
   }
 
   void tearDown() {
@@ -36,6 +36,7 @@ class TestVM : public CxxTest::TestSuite {
   }
 
   void test_globals() {
-    TS_ASSERT_EQUALS(state-&gt;globals.roots.size(), 120);
+    TS_ASSERT_EQUALS(state-&gt;globals.roots.size(), 121);
   }
+
 };</diff>
      <filename>vm/test/test_vm.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -1,9 +1,18 @@
+#include &quot;builtin.hpp&quot;
 #include &quot;type_info.hpp&quot;
-#include &quot;objects.hpp&quot;
 
 namespace rubinius {
-  TypeInfo::TypeInfo(Class *cls) {
-    type = (object_type)cls-&gt;instance_type-&gt;n2i();
+  TypeInfo::TypeInfo(object_type type) : type(type) {
     state = NULL;
   }
+
+  void TypeInfo::set_field(STATE, OBJECT target, size_t index, OBJECT val) {
+    throw std::runtime_error(&quot;field access denied&quot;);
+  }
+
+  OBJECT TypeInfo::get_field(STATE, OBJECT target, size_t index) {
+    throw std::runtime_error(&quot;unable to access field&quot;);
+  }
+
+#include &quot;gen/typechecks.gen.cpp&quot;
 }</diff>
      <filename>vm/type_info.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -4,20 +4,30 @@
 #include &quot;prelude.hpp&quot;
 #include &quot;object.hpp&quot;
 
+#include &lt;map&gt;
+#include &lt;stdexcept&gt;
+
 namespace rubinius {
   class VM;
   class Class;
 
   /* TypeInfo contains varies operations that are registered by types */
   class TypeInfo {
-    public:
+  public:
+
+    typedef std::map&lt;native_int, long&gt; Slots;
+
     VM* state;
     object_type type;
+    Slots slots;
 
-    TypeInfo(Class* cls);
+    static void init(STATE);
+    TypeInfo(object_type type);
     virtual ~TypeInfo() { }
     virtual void cleanup(OBJECT obj) { }
     virtual void mark(OBJECT obj) { }
+    virtual void set_field(STATE, OBJECT target, size_t index, OBJECT val);
+    virtual OBJECT get_field(STATE, OBJECT target, size_t index);
   };
 }
 </diff>
      <filename>vm/type_info.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -4,13 +4,17 @@
 #include &quot;event.hpp&quot;
 #include &quot;global_cache.hpp&quot;
 
+#include &lt;iostream&gt;
+
 namespace rubinius {
-  VM::VM(size_t bytes) {
+  VM::VM(size_t bytes) : wait_events(false) {
     om = new ObjectMemory(bytes);
     bootstrap_ontology();
 
     events = new event::Loop(EVFLAG_FORKCHECK);
     global_cache = new GlobalCache;
+
+    boot_threads();
   }
 
   VM::~VM() {
@@ -19,6 +23,13 @@ namespace rubinius {
     delete global_cache;
   }
 
+  void VM::boot_threads() {
+    Thread* thr = Thread::create(this);
+    thr-&gt;boot_task(this);
+
+    activate_thread(thr);
+  }
+
   OBJECT VM::new_object(Class *cls) {
     return om-&gt;new_object(cls, cls-&gt;instance_fields-&gt;n2i());
   }
@@ -54,7 +65,26 @@ namespace rubinius {
   }
 
   void VM::run_best_thread() {
-    throw new DeadLock(&quot;no runnable threads, present or future.&quot;);
+    Thread* next = NULL;
+
+    events-&gt;poll();
+
+    for(size_t i = 0; i &lt; globals.scheduled_threads-&gt;field_count; i++) {
+      List* lst = as&lt;List&gt;(globals.scheduled_threads-&gt;at(i));
+      if(lst-&gt;empty_p()) continue;
+      next = as&lt;Thread&gt;(lst-&gt;shift(this));
+    }
+
+    if(!next) {
+      if(events-&gt;num_of_events() == 0) {
+        throw new DeadLock(&quot;no runnable threads, present or future.&quot;);
+      }
+
+      wait_events = true;
+      return;
+    }
+
+    activate_thread(next);
   }
 
   void VM::return_value(OBJECT val) {
@@ -70,4 +100,31 @@ namespace rubinius {
     globals.current_thread.set(thread);
     globals.current_task.set(thread-&gt;task);
   }
+
+  OBJECT VM::current_block() {
+    return globals.current_task-&gt;active-&gt;block;
+  }
+
+  void VM::raise_from_errno(char* msg) {
+
+  }
+
+  void VM::inspect(OBJECT obj) {
+    if(obj-&gt;symbol_p()) {
+      String* str = as&lt;Symbol&gt;(obj)-&gt;to_str(this);
+      std::cout &lt;&lt; &quot;&lt;Symbol :&quot; &lt;&lt; (char*)*str &lt;&lt; &quot;&gt;&quot; &lt;&lt; std::endl;
+    } else if(obj-&gt;fixnum_p()) {
+      std::cout &lt;&lt; &quot;&lt;Fixnum &quot; &lt;&lt; as&lt;Fixnum&gt;(obj)-&gt;to_nint() &lt;&lt; &quot;&gt;&quot; &lt;&lt; std::endl;
+    } else {
+      std::cout &lt;&lt; &quot;&lt;Object: &quot; &lt;&lt; (void*)obj &lt;&lt; &quot;&gt;&quot; &lt;&lt; std::endl;
+    }
+  }
+
+  void VM::set_const(const char* name, OBJECT val) {
+    globals.object-&gt;set_const(this, (char*)name, val);
+  }
+  
+  void VM::set_const(Module* mod, const char* name, OBJECT val) {
+    mod-&gt;set_const(this, (char*)name, val);
+  }
 };</diff>
      <filename>vm/vm.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -6,6 +6,8 @@
 
 namespace rubinius {
 
+  class Exception;
+
   namespace event {
     class Loop;
   }
@@ -20,6 +22,8 @@ namespace rubinius {
     event::Loop* events;
     GlobalCache* global_cache;
 
+    bool wait_events;
+
     static const size_t default_bytes = 10240;
 
     /* Inline methods */
@@ -30,6 +34,7 @@ namespace rubinius {
     void bootstrap_ontology();
     void bootstrap_symbol();
     void bootstrap_exceptions();
+    void boot_threads();
 
     OBJECT new_object(Class* cls);
     Class* new_basic_class(OBJECT sup, size_t fields);
@@ -52,6 +57,14 @@ namespace rubinius {
     void run_best_thread();
     void queue_thread(Thread* thread);
     void activate_thread(Thread* thread);
+    void raise_from_errno(char* reason);
+    void raise_exception(Exception* exc);
+    Exception* new_exception(Class* cls, char* msg);
+    OBJECT current_block();
+
+    void inspect(OBJECT obj);
+    void set_const(const char* name, OBJECT val);
+    void set_const(Module* mod, const char* name, OBJECT val);
 
   };
 };</diff>
      <filename>vm/vm.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -1,13 +1,13 @@
 #include &quot;objects.hpp&quot;
 
 namespace rubinius {
-  VMMethod::VMMethod(CompiledMethod* meth) {
-    size_t total = meth-&gt;iseq-&gt;instructions-&gt;field_count;
+  VMMethod::VMMethod(CompiledMethod* meth) : original(meth) {
+    total = meth-&gt;iseq-&gt;opcodes-&gt;field_count;
 
     opcodes = new opcode[total];
 
     for(size_t index = 0; index &lt; total; index++) {
-      OBJECT val = meth-&gt;iseq-&gt;instructions-&gt;at(index);
+      OBJECT val = meth-&gt;iseq-&gt;opcodes-&gt;at(index);
       if(val-&gt;nil_p()) {
         opcodes[index] = 0;
       } else {
@@ -23,4 +23,21 @@ namespace rubinius {
   VMMethod::~VMMethod() {
     delete[] opcodes;
   }
+
+  void VMMethod::specialize(TypeInfo* ti) {
+    for(size_t i = 0; i &lt; total; i++) {
+      opcode op = opcodes[i];
+      
+      if(op == InstructionSequence::insn_push_ivar) {
+        native_int idx = opcodes[i + 1];
+        native_int sym = as&lt;Symbol&gt;(original-&gt;literals-&gt;at(idx))-&gt;index();
+
+        TypeInfo::Slots::iterator it = ti-&gt;slots.find(sym);
+        if(it != ti-&gt;slots.end()) {
+          opcodes[i] = InstructionSequence::insn_push_my_field;
+          opcodes[++i] = it-&gt;second;
+        }
+      }
+    }
+  }
 }</diff>
      <filename>vm/vmmethod.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -10,11 +10,14 @@ namespace rubinius {
     static instlocation* instructions;
 
     opcode* opcodes;
+    size_t total;
     CompiledMethod* original;
 
     VMMethod(CompiledMethod* meth);
     VMMethod(size_t fields);
     ~VMMethod();
+
+    void specialize(TypeInfo* ti);
   };
 };
 </diff>
      <filename>vm/vmmethod.hpp</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>runtime/stable/bootstrap.rba</filename>
    </removed>
    <removed>
      <filename>runtime/stable/compiler.rba</filename>
    </removed>
    <removed>
      <filename>runtime/stable/core.rba</filename>
    </removed>
    <removed>
      <filename>runtime/stable/loader.rbc</filename>
    </removed>
    <removed>
      <filename>runtime/stable/platform.rba</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>611cd7440cacf3fa3c730f5093dc66e3f8e33d2e</id>
    </parent>
  </parents>
  <author>
    <name>Evan Phoenix</name>
    <email>ephoenix@engineyard.com</email>
  </author>
  <url>http://github.com/evanphx/rubinius/commit/feb91b43f113f8dc3b5e28c569cabc0a9c3d508c</url>
  <id>feb91b43f113f8dc3b5e28c569cabc0a9c3d508c</id>
  <committed-date>2008-05-07T18:05:09-07:00</committed-date>
  <authored-date>2008-05-07T18:05:09-07:00</authored-date>
  <message>Tons of stuff (too much probably)</message>
  <tree>8fc9bbf14c77c67c4d0726c48eb93c3a27ed69a5</tree>
  <committer>
    <name>Evan Phoenix</name>
    <email>ephoenix@engineyard.com</email>
  </committer>
</commit>
