You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2013/07/17 16:12:24 UTC

[lucy-commits] [04/34] Update Lucy search classes with IVARS.

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/PhraseQuery.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/PhraseQuery.c b/core/Lucy/Search/PhraseQuery.c
index e388773..2c62e2f 100644
--- a/core/Lucy/Search/PhraseQuery.c
+++ b/core/Lucy/Search/PhraseQuery.c
@@ -56,27 +56,30 @@ PhraseQuery_init(PhraseQuery *self, const CharBuf *field, VArray *terms) {
 
 void
 PhraseQuery_destroy(PhraseQuery *self) {
-    DECREF(self->terms);
-    DECREF(self->field);
+    PhraseQueryIVARS *const ivars = PhraseQuery_IVARS(self);
+    DECREF(ivars->terms);
+    DECREF(ivars->field);
     SUPER_DESTROY(self, PHRASEQUERY);
 }
 
 static PhraseQuery*
 S_do_init(PhraseQuery *self, CharBuf *field, VArray *terms, float boost) {
     Query_init((Query*)self, boost);
+    PhraseQueryIVARS *const ivars = PhraseQuery_IVARS(self);
     for (uint32_t i = 0, max = VA_Get_Size(terms); i < max; i++) {
         CERTIFY(VA_Fetch(terms, i), OBJ);
     }
-    self->field = field;
-    self->terms = terms;
+    ivars->field = field;
+    ivars->terms = terms;
     return self;
 }
 
 void
 PhraseQuery_serialize(PhraseQuery *self, OutStream *outstream) {
-    OutStream_Write_F32(outstream, self->boost);
-    Freezer_serialize_charbuf(self->field, outstream);
-    Freezer_serialize_varray(self->terms, outstream);
+    PhraseQueryIVARS *const ivars = PhraseQuery_IVARS(self);
+    OutStream_Write_F32(outstream, ivars->boost);
+    Freezer_serialize_charbuf(ivars->field, outstream);
+    Freezer_serialize_varray(ivars->terms, outstream);
 }
 
 PhraseQuery*
@@ -89,26 +92,28 @@ PhraseQuery_deserialize(PhraseQuery *self, InStream *instream) {
 
 bool
 PhraseQuery_equals(PhraseQuery *self, Obj *other) {
-    PhraseQuery *twin = (PhraseQuery*)other;
-    if (twin == self)                  { return true; }
+    if ((PhraseQuery*)other == self)   { return true; }
     if (!Obj_Is_A(other, PHRASEQUERY)) { return false; }
-    if (self->boost != twin->boost)    { return false; }
-    if (self->field && !twin->field)   { return false; }
-    if (!self->field && twin->field)   { return false; }
-    if (self->field && !CB_Equals(self->field, (Obj*)twin->field)) {
+    PhraseQueryIVARS *const ivars = PhraseQuery_IVARS(self);
+    PhraseQueryIVARS *const ovars = PhraseQuery_IVARS((PhraseQuery*)other);
+    if (ivars->boost != ovars->boost)  { return false; }
+    if (ivars->field && !ovars->field) { return false; }
+    if (!ivars->field && ovars->field) { return false; }
+    if (ivars->field && !CB_Equals(ivars->field, (Obj*)ovars->field)) {
         return false;
     }
-    if (!VA_Equals(twin->terms, (Obj*)self->terms)) { return false; }
+    if (!VA_Equals(ovars->terms, (Obj*)ivars->terms)) { return false; }
     return true;
 }
 
 CharBuf*
 PhraseQuery_to_string(PhraseQuery *self) {
-    uint32_t  num_terms = VA_Get_Size(self->terms);
-    CharBuf  *retval    = CB_Clone(self->field);
+    PhraseQueryIVARS *const ivars = PhraseQuery_IVARS(self);
+    uint32_t  num_terms = VA_Get_Size(ivars->terms);
+    CharBuf  *retval    = CB_Clone(ivars->field);
     CB_Cat_Trusted_Str(retval, ":\"", 2);
     for (uint32_t i = 0; i < num_terms; i++) {
-        Obj     *term        = VA_Fetch(self->terms, i);
+        Obj     *term        = VA_Fetch(ivars->terms, i);
         CharBuf *term_string = Obj_To_String(term);
         CB_Cat(retval, term_string);
         DECREF(term_string);
@@ -123,12 +128,13 @@ PhraseQuery_to_string(PhraseQuery *self) {
 Compiler*
 PhraseQuery_make_compiler(PhraseQuery *self, Searcher *searcher,
                           float boost, bool subordinate) {
-    if (VA_Get_Size(self->terms) == 1) {
+    PhraseQueryIVARS *const ivars = PhraseQuery_IVARS(self);
+    if (VA_Get_Size(ivars->terms) == 1) {
         // Optimize for one-term "phrases".
-        Obj *term = VA_Fetch(self->terms, 0);
-        TermQuery *term_query = TermQuery_new(self->field, term);
+        Obj *term = VA_Fetch(ivars->terms, 0);
+        TermQuery *term_query = TermQuery_new(ivars->field, term);
         TermCompiler *term_compiler;
-        TermQuery_Set_Boost(term_query, self->boost);
+        TermQuery_Set_Boost(term_query, ivars->boost);
         term_compiler
             = (TermCompiler*)TermQuery_Make_Compiler(term_query, searcher,
                                                      boost, subordinate);
@@ -147,12 +153,12 @@ PhraseQuery_make_compiler(PhraseQuery *self, Searcher *searcher,
 
 CharBuf*
 PhraseQuery_get_field(PhraseQuery *self) {
-    return self->field;
+    return PhraseQuery_IVARS(self)->field;
 }
 
 VArray*
 PhraseQuery_get_terms(PhraseQuery *self) {
-    return self->terms;
+    return PhraseQuery_IVARS(self)->terms;
 }
 
 /*********************************************************************/
@@ -166,9 +172,11 @@ PhraseCompiler_new(PhraseQuery *parent, Searcher *searcher, float boost) {
 PhraseCompiler*
 PhraseCompiler_init(PhraseCompiler *self, PhraseQuery *parent,
                     Searcher *searcher, float boost) {
+    PhraseCompilerIVARS *const ivars = PhraseCompiler_IVARS(self);
+    PhraseQueryIVARS *const parent_ivars = PhraseQuery_IVARS(parent);
     Schema     *schema = Searcher_Get_Schema(searcher);
-    Similarity *sim    = Schema_Fetch_Sim(schema, parent->field);
-    VArray     *terms  = parent->terms;
+    Similarity *sim    = Schema_Fetch_Sim(schema, parent_ivars->field);
+    VArray     *terms  = parent_ivars->terms;
 
     // Try harder to find a Similarity if necessary.
     if (!sim) { sim = Schema_Get_Similarity(schema); }
@@ -177,27 +185,28 @@ PhraseCompiler_init(PhraseCompiler *self, PhraseQuery *parent,
     Compiler_init((Compiler*)self, (Query*)parent, searcher, sim, boost);
 
     // Store IDF for the phrase.
-    self->idf = 0;
+    ivars->idf = 0;
     for (uint32_t i = 0, max = VA_Get_Size(terms); i < max; i++) {
         Obj     *term     = VA_Fetch(terms, i);
         int32_t  doc_max  = Searcher_Doc_Max(searcher);
-        int32_t  doc_freq = Searcher_Doc_Freq(searcher, parent->field, term);
-        self->idf += Sim_IDF(sim, doc_freq, doc_max);
+        int32_t  doc_freq = Searcher_Doc_Freq(searcher, parent_ivars->field, term);
+        ivars->idf += Sim_IDF(sim, doc_freq, doc_max);
     }
 
     // Calculate raw weight.
-    self->raw_weight = self->idf * self->boost;
+    ivars->raw_weight = ivars->idf * ivars->boost;
 
     return self;
 }
 
 void
 PhraseCompiler_serialize(PhraseCompiler *self, OutStream *outstream) {
+    PhraseCompilerIVARS *const ivars = PhraseCompiler_IVARS(self);
     Compiler_serialize((Compiler*)self, outstream);
-    OutStream_Write_F32(outstream, self->idf);
-    OutStream_Write_F32(outstream, self->raw_weight);
-    OutStream_Write_F32(outstream, self->query_norm_factor);
-    OutStream_Write_F32(outstream, self->normalized_weight);
+    OutStream_Write_F32(outstream, ivars->idf);
+    OutStream_Write_F32(outstream, ivars->raw_weight);
+    OutStream_Write_F32(outstream, ivars->query_norm_factor);
+    OutStream_Write_F32(outstream, ivars->normalized_weight);
 }
 
 PhraseCompiler*
@@ -205,47 +214,54 @@ PhraseCompiler_deserialize(PhraseCompiler *self, InStream *instream) {
     PhraseCompiler_Deserialize_t super_deserialize
         = SUPER_METHOD_PTR(PHRASECOMPILER, Lucy_PhraseCompiler_Deserialize);
     self = super_deserialize(self, instream);
-    self->idf               = InStream_Read_F32(instream);
-    self->raw_weight        = InStream_Read_F32(instream);
-    self->query_norm_factor = InStream_Read_F32(instream);
-    self->normalized_weight = InStream_Read_F32(instream);
+    PhraseCompilerIVARS *const ivars = PhraseCompiler_IVARS(self);
+    ivars->idf               = InStream_Read_F32(instream);
+    ivars->raw_weight        = InStream_Read_F32(instream);
+    ivars->query_norm_factor = InStream_Read_F32(instream);
+    ivars->normalized_weight = InStream_Read_F32(instream);
     return self;
 }
 
 bool
 PhraseCompiler_equals(PhraseCompiler *self, Obj *other) {
-    PhraseCompiler *twin = (PhraseCompiler*)other;
-    if (!Obj_Is_A(other, PHRASECOMPILER))                   { return false; }
-    if (!Compiler_equals((Compiler*)self, other))           { return false; }
-    if (self->idf != twin->idf)                             { return false; }
-    if (self->raw_weight != twin->raw_weight)               { return false; }
-    if (self->query_norm_factor != twin->query_norm_factor) { return false; }
-    if (self->normalized_weight != twin->normalized_weight) { return false; }
+    if (!Obj_Is_A(other, PHRASECOMPILER))                     { return false; }
+    if (!Compiler_equals((Compiler*)self, other))             { return false; }
+    PhraseCompilerIVARS *const ivars = PhraseCompiler_IVARS(self);
+    PhraseCompilerIVARS *const ovars
+        = PhraseCompiler_IVARS((PhraseCompiler*)other);
+    if (ivars->idf != ovars->idf)                             { return false; }
+    if (ivars->raw_weight != ovars->raw_weight)               { return false; }
+    if (ivars->query_norm_factor != ovars->query_norm_factor) { return false; }
+    if (ivars->normalized_weight != ovars->normalized_weight) { return false; }
     return true;
 }
 
 float
 PhraseCompiler_get_weight(PhraseCompiler *self) {
-    return self->normalized_weight;
+    return PhraseCompiler_IVARS(self)->normalized_weight;
 }
 
 float
 PhraseCompiler_sum_of_squared_weights(PhraseCompiler *self) {
-    return self->raw_weight * self->raw_weight;
+    PhraseCompilerIVARS *const ivars = PhraseCompiler_IVARS(self);
+    return ivars->raw_weight * ivars->raw_weight;
 }
 
 void
 PhraseCompiler_apply_norm_factor(PhraseCompiler *self, float factor) {
-    self->query_norm_factor = factor;
-    self->normalized_weight = self->raw_weight * self->idf * factor;
+    PhraseCompilerIVARS *const ivars = PhraseCompiler_IVARS(self);
+    ivars->query_norm_factor = factor;
+    ivars->normalized_weight = ivars->raw_weight * ivars->idf * factor;
 }
 
 Matcher*
 PhraseCompiler_make_matcher(PhraseCompiler *self, SegReader *reader,
                             bool need_score) {
     UNUSED_VAR(need_score);
-    PhraseQuery *const parent    = (PhraseQuery*)self->parent;
-    VArray *const      terms     = parent->terms;
+    PhraseCompilerIVARS *const ivars = PhraseCompiler_IVARS(self);
+    PhraseQueryIVARS *const parent_ivars
+        = PhraseQuery_IVARS((PhraseQuery*)ivars->parent);
+    VArray *const      terms     = parent_ivars->terms;
     uint32_t           num_terms = VA_Get_Size(terms);
 
     // Bail if there are no terms.
@@ -271,7 +287,7 @@ PhraseCompiler_make_matcher(PhraseCompiler *self, SegReader *reader,
     for (uint32_t i = 0; i < num_terms; i++) {
         Obj *term = VA_Fetch(terms, i);
         PostingList *plist
-            = PListReader_Posting_List(plist_reader, parent->field, term);
+            = PListReader_Posting_List(plist_reader, parent_ivars->field, term);
 
         // Bail if any one of the terms isn't in the index.
         if (!plist || !PList_Get_Doc_Freq(plist)) {
@@ -291,15 +307,17 @@ PhraseCompiler_make_matcher(PhraseCompiler *self, SegReader *reader,
 VArray*
 PhraseCompiler_highlight_spans(PhraseCompiler *self, Searcher *searcher,
                                DocVector *doc_vec, const CharBuf *field) {
-    PhraseQuery *const parent    = (PhraseQuery*)self->parent;
-    VArray *const      terms     = parent->terms;
+    PhraseCompilerIVARS *const ivars = PhraseCompiler_IVARS(self);
+    PhraseQueryIVARS *const parent_ivars
+        = PhraseQuery_IVARS((PhraseQuery*)ivars->parent);
+    VArray *const      terms     = parent_ivars->terms;
     VArray *const      spans     = VA_new(0);
     const uint32_t     num_terms = VA_Get_Size(terms);
     UNUSED_VAR(searcher);
 
     // Bail if no terms or field doesn't match.
     if (!num_terms) { return spans; }
-    if (!CB_Equals(field, (Obj*)parent->field)) { return spans; }
+    if (!CB_Equals(field, (Obj*)parent_ivars->field)) { return spans; }
 
     VArray *term_vectors    = VA_new(num_terms);
     BitVector *posit_vec       = BitVec_new(0);

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/PolyMatcher.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/PolyMatcher.c b/core/Lucy/Search/PolyMatcher.c
index 4e1b38c..8c91be0 100644
--- a/core/Lucy/Search/PolyMatcher.c
+++ b/core/Lucy/Search/PolyMatcher.c
@@ -29,13 +29,14 @@ PolyMatcher_new(VArray *children, Similarity *sim) {
 PolyMatcher*
 PolyMatcher_init(PolyMatcher *self, VArray *children, Similarity *similarity) {
     Matcher_init((Matcher*)self);
-    self->num_kids = VA_Get_Size(children);
-    self->sim      = (Similarity*)INCREF(similarity);
-    self->children = (VArray*)INCREF(children);
-    self->coord_factors = (float*)MALLOCATE((self->num_kids + 1) * sizeof(float));
-    for (uint32_t i = 0; i <= self->num_kids; i++) {
-        self->coord_factors[i] = similarity
-                                 ? Sim_Coord(similarity, i, self->num_kids)
+    PolyMatcherIVARS *const ivars = PolyMatcher_IVARS(self);
+    ivars->num_kids = VA_Get_Size(children);
+    ivars->sim      = (Similarity*)INCREF(similarity);
+    ivars->children = (VArray*)INCREF(children);
+    ivars->coord_factors = (float*)MALLOCATE((ivars->num_kids + 1) * sizeof(float));
+    for (uint32_t i = 0; i <= ivars->num_kids; i++) {
+        ivars->coord_factors[i] = similarity
+                                 ? Sim_Coord(similarity, i, ivars->num_kids)
                                  : 1.0f;
     }
     return self;
@@ -43,9 +44,10 @@ PolyMatcher_init(PolyMatcher *self, VArray *children, Similarity *similarity) {
 
 void
 PolyMatcher_destroy(PolyMatcher *self) {
-    DECREF(self->children);
-    DECREF(self->sim);
-    FREEMEM(self->coord_factors);
+    PolyMatcherIVARS *const ivars = PolyMatcher_IVARS(self);
+    DECREF(ivars->children);
+    DECREF(ivars->sim);
+    FREEMEM(ivars->coord_factors);
     SUPER_DESTROY(self, POLYMATCHER);
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/PolyQuery.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/PolyQuery.c b/core/Lucy/Search/PolyQuery.c
index e116aaf..da87dc1 100644
--- a/core/Lucy/Search/PolyQuery.c
+++ b/core/Lucy/Search/PolyQuery.c
@@ -32,7 +32,8 @@ PolyQuery*
 PolyQuery_init(PolyQuery *self, VArray *children) {
     const uint32_t num_kids = children ? VA_Get_Size(children) : 0;
     Query_init((Query*)self, 1.0f);
-    self->children = VA_new(num_kids);
+    PolyQueryIVARS *const ivars = PolyQuery_IVARS(self);
+    ivars->children = VA_new(num_kids);
     for (uint32_t i = 0; i < num_kids; i++) {
         PolyQuery_Add_Child(self, (Query*)VA_Fetch(children, i));
     }
@@ -41,34 +42,38 @@ PolyQuery_init(PolyQuery *self, VArray *children) {
 
 void
 PolyQuery_destroy(PolyQuery *self) {
-    DECREF(self->children);
+    PolyQueryIVARS *const ivars = PolyQuery_IVARS(self);
+    DECREF(ivars->children);
     SUPER_DESTROY(self, POLYQUERY);
 }
 
 void
 PolyQuery_add_child(PolyQuery *self, Query *query) {
     CERTIFY(query, QUERY);
-    VA_Push(self->children, INCREF(query));
+    PolyQueryIVARS *const ivars = PolyQuery_IVARS(self);
+    VA_Push(ivars->children, INCREF(query));
 }
 
 void
 PolyQuery_set_children(PolyQuery *self, VArray *children) {
-    DECREF(self->children);
-    self->children = (VArray*)INCREF(children);
+    PolyQueryIVARS *const ivars = PolyQuery_IVARS(self);
+    DECREF(ivars->children);
+    ivars->children = (VArray*)INCREF(children);
 }
 
 VArray*
 PolyQuery_get_children(PolyQuery *self) {
-    return self->children;
+    return PolyQuery_IVARS(self)->children;
 }
 
 void
 PolyQuery_serialize(PolyQuery *self, OutStream *outstream) {
-    const uint32_t num_kids = VA_Get_Size(self->children);
-    OutStream_Write_F32(outstream, self->boost);
+    PolyQueryIVARS *const ivars = PolyQuery_IVARS(self);
+    const uint32_t num_kids = VA_Get_Size(ivars->children);
+    OutStream_Write_F32(outstream, ivars->boost);
     OutStream_Write_U32(outstream, num_kids);
     for (uint32_t i = 0; i < num_kids; i++) {
-        Query *child = (Query*)VA_Fetch(self->children, i);
+        Query *child = (Query*)VA_Fetch(ivars->children, i);
         FREEZE(child, outstream);
     }
 }
@@ -78,21 +83,23 @@ PolyQuery_deserialize(PolyQuery *self, InStream *instream) {
     float    boost        = InStream_Read_F32(instream);
     uint32_t num_children = InStream_Read_U32(instream);
     PolyQuery_init(self, NULL);
+    PolyQueryIVARS *const ivars = PolyQuery_IVARS(self);
     PolyQuery_Set_Boost(self, boost);
-    VA_Grow(self->children, num_children);
+    VA_Grow(ivars->children, num_children);
     while (num_children--) {
-        VA_Push(self->children, THAW(instream));
+        VA_Push(ivars->children, THAW(instream));
     }
     return self;
 }
 
 bool
 PolyQuery_equals(PolyQuery *self, Obj *other) {
-    PolyQuery *twin = (PolyQuery*)other;
-    if (twin == self)                                     { return true; }
-    if (!Obj_Is_A(other, POLYQUERY))                      { return false; }
-    if (self->boost != twin->boost)                       { return false; }
-    if (!VA_Equals(twin->children, (Obj*)self->children)) { return false; }
+    if ((PolyQuery*)other == self)                          { return true; }
+    if (!Obj_Is_A(other, POLYQUERY))                        { return false; }
+    PolyQueryIVARS *const ivars = PolyQuery_IVARS(self);
+    PolyQueryIVARS *const ovars = PolyQuery_IVARS((PolyQuery*)other);
+    if (ivars->boost != ovars->boost)                       { return false; }
+    if (!VA_Equals(ovars->children, (Obj*)ivars->children)) { return false; }
     return true;
 }
 
@@ -102,18 +109,20 @@ PolyQuery_equals(PolyQuery *self, Obj *other) {
 PolyCompiler*
 PolyCompiler_init(PolyCompiler *self, PolyQuery *parent,
                   Searcher *searcher, float boost) {
-    const uint32_t num_kids = VA_Get_Size(parent->children);
+    PolyCompilerIVARS *const ivars = PolyCompiler_IVARS(self);
+    PolyQueryIVARS *const parent_ivars = PolyQuery_IVARS(parent);
+    const uint32_t num_kids = VA_Get_Size(parent_ivars->children);
 
     Compiler_init((Compiler*)self, (Query*)parent, searcher, NULL, boost);
-    self->children = VA_new(num_kids);
+    ivars->children = VA_new(num_kids);
 
     // Iterate over the children, creating a Compiler for each one.
     for (uint32_t i = 0; i < num_kids; i++) {
-        Query *child_query = (Query*)VA_Fetch(parent->children, i);
+        Query *child_query = (Query*)VA_Fetch(parent_ivars->children, i);
         float sub_boost = boost * Query_Get_Boost(child_query);
         Compiler *child_compiler
             = Query_Make_Compiler(child_query, searcher, sub_boost, true);
-        VA_Push(self->children, (Obj*)child_compiler);
+        VA_Push(ivars->children, (Obj*)child_compiler);
     }
 
     return self;
@@ -121,17 +130,19 @@ PolyCompiler_init(PolyCompiler *self, PolyQuery *parent,
 
 void
 PolyCompiler_destroy(PolyCompiler *self) {
-    DECREF(self->children);
+    PolyCompilerIVARS *const ivars = PolyCompiler_IVARS(self);
+    DECREF(ivars->children);
     SUPER_DESTROY(self, POLYCOMPILER);
 }
 
 float
 PolyCompiler_sum_of_squared_weights(PolyCompiler *self) {
+    PolyCompilerIVARS *const ivars = PolyCompiler_IVARS(self);
     float sum      = 0;
     float my_boost = PolyCompiler_Get_Boost(self);
 
-    for (uint32_t i = 0, max = VA_Get_Size(self->children); i < max; i++) {
-        Compiler *child = (Compiler*)VA_Fetch(self->children, i);
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->children); i < max; i++) {
+        Compiler *child = (Compiler*)VA_Fetch(ivars->children, i);
         sum += Compiler_Sum_Of_Squared_Weights(child);
     }
 
@@ -143,8 +154,9 @@ PolyCompiler_sum_of_squared_weights(PolyCompiler *self) {
 
 void
 PolyCompiler_apply_norm_factor(PolyCompiler *self, float factor) {
-    for (uint32_t i = 0, max = VA_Get_Size(self->children); i < max; i++) {
-        Compiler *child = (Compiler*)VA_Fetch(self->children, i);
+    PolyCompilerIVARS *const ivars = PolyCompiler_IVARS(self);
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->children); i < max; i++) {
+        Compiler *child = (Compiler*)VA_Fetch(ivars->children, i);
         Compiler_Apply_Norm_Factor(child, factor);
     }
 }
@@ -152,9 +164,10 @@ PolyCompiler_apply_norm_factor(PolyCompiler *self, float factor) {
 VArray*
 PolyCompiler_highlight_spans(PolyCompiler *self, Searcher *searcher,
                              DocVector *doc_vec, const CharBuf *field) {
+    PolyCompilerIVARS *const ivars = PolyCompiler_IVARS(self);
     VArray *spans = VA_new(0);
-    for (uint32_t i = 0, max = VA_Get_Size(self->children); i < max; i++) {
-        Compiler *child = (Compiler*)VA_Fetch(self->children, i);
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->children); i < max; i++) {
+        Compiler *child = (Compiler*)VA_Fetch(ivars->children, i);
         VArray *child_spans = Compiler_Highlight_Spans(child, searcher,
                                                        doc_vec, field);
         if (child_spans) {
@@ -167,8 +180,9 @@ PolyCompiler_highlight_spans(PolyCompiler *self, Searcher *searcher,
 
 void
 PolyCompiler_serialize(PolyCompiler *self, OutStream *outstream) {
+    PolyCompilerIVARS *const ivars = PolyCompiler_IVARS(self);
     Freezer_serialize_charbuf(PolyCompiler_Get_Class_Name(self), outstream);
-    Freezer_serialize_varray(self->children, outstream);
+    Freezer_serialize_varray(ivars->children, outstream);
     PolyCompiler_Serialize_t super_serialize
         = SUPER_METHOD_PTR(POLYCOMPILER, Lucy_PolyCompiler_Serialize);
     super_serialize(self, outstream);
@@ -176,9 +190,10 @@ PolyCompiler_serialize(PolyCompiler *self, OutStream *outstream) {
 
 PolyCompiler*
 PolyCompiler_deserialize(PolyCompiler *self, InStream *instream) {
+    PolyCompilerIVARS *const ivars = PolyCompiler_IVARS(self);
     CharBuf *class_name = Freezer_read_charbuf(instream);
     DECREF(class_name); // TODO Don't serialize class name.
-    self->children = Freezer_read_varray(instream);
+    ivars->children = Freezer_read_varray(instream);
     PolyCompiler_Deserialize_t super_deserialize
         = SUPER_METHOD_PTR(POLYCOMPILER, Lucy_PolyCompiler_Deserialize);
     return super_deserialize(self, instream);

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/PolySearcher.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/PolySearcher.c b/core/Lucy/Search/PolySearcher.c
index 6789f4c..a7fea42 100644
--- a/core/Lucy/Search/PolySearcher.c
+++ b/core/Lucy/Search/PolySearcher.c
@@ -40,8 +40,9 @@ PolySearcher_init(PolySearcher *self, Schema *schema, VArray *searchers) {
     int32_t  doc_max      = 0;
 
     Searcher_init((Searcher*)self, schema);
-    self->searchers = (VArray*)INCREF(searchers);
-    self->starts = NULL; // Safe cleanup.
+    PolySearcherIVARS *const ivars = PolySearcher_IVARS(self);
+    ivars->searchers = (VArray*)INCREF(searchers);
+    ivars->starts = NULL; // Safe cleanup.
 
     for (uint32_t i = 0; i < num_searchers; i++) {
         Searcher *searcher
@@ -62,24 +63,26 @@ PolySearcher_init(PolySearcher *self, Schema *schema, VArray *searchers) {
         doc_max += Searcher_Doc_Max(searcher);
     }
 
-    self->doc_max = doc_max;
-    self->starts  = I32Arr_new_steal(starts_array, num_searchers);
+    ivars->doc_max = doc_max;
+    ivars->starts  = I32Arr_new_steal(starts_array, num_searchers);
 
     return self;
 }
 
 void
 PolySearcher_destroy(PolySearcher *self) {
-    DECREF(self->searchers);
-    DECREF(self->starts);
+    PolySearcherIVARS *const ivars = PolySearcher_IVARS(self);
+    DECREF(ivars->searchers);
+    DECREF(ivars->starts);
     SUPER_DESTROY(self, POLYSEARCHER);
 }
 
 HitDoc*
 PolySearcher_fetch_doc(PolySearcher *self, int32_t doc_id) {
-    uint32_t  tick     = PolyReader_sub_tick(self->starts, doc_id);
-    Searcher *searcher = (Searcher*)VA_Fetch(self->searchers, tick);
-    int32_t   offset   = I32Arr_Get(self->starts, tick);
+    PolySearcherIVARS *const ivars = PolySearcher_IVARS(self);
+    uint32_t  tick     = PolyReader_sub_tick(ivars->starts, doc_id);
+    Searcher *searcher = (Searcher*)VA_Fetch(ivars->searchers, tick);
+    int32_t   offset   = I32Arr_Get(ivars->starts, tick);
     if (!searcher) { THROW(ERR, "Invalid doc id: %i32", doc_id); }
     HitDoc *hit_doc = Searcher_Fetch_Doc(searcher, doc_id - offset);
     HitDoc_Set_Doc_ID(hit_doc, doc_id);
@@ -88,23 +91,25 @@ PolySearcher_fetch_doc(PolySearcher *self, int32_t doc_id) {
 
 DocVector*
 PolySearcher_fetch_doc_vec(PolySearcher *self, int32_t doc_id) {
-    uint32_t  tick     = PolyReader_sub_tick(self->starts, doc_id);
-    Searcher *searcher = (Searcher*)VA_Fetch(self->searchers, tick);
-    int32_t   start    = I32Arr_Get(self->starts, tick);
+    PolySearcherIVARS *const ivars = PolySearcher_IVARS(self);
+    uint32_t  tick     = PolyReader_sub_tick(ivars->starts, doc_id);
+    Searcher *searcher = (Searcher*)VA_Fetch(ivars->searchers, tick);
+    int32_t   start    = I32Arr_Get(ivars->starts, tick);
     if (!searcher) { THROW(ERR, "Invalid doc id: %i32", doc_id); }
     return Searcher_Fetch_Doc_Vec(searcher, doc_id - start);
 }
 
 int32_t
 PolySearcher_doc_max(PolySearcher *self) {
-    return self->doc_max;
+    return PolySearcher_IVARS(self)->doc_max;
 }
 
 uint32_t
 PolySearcher_doc_freq(PolySearcher *self, const CharBuf *field, Obj *term) {
+    PolySearcherIVARS *const ivars = PolySearcher_IVARS(self);
     uint32_t doc_freq = 0;
-    for (uint32_t i = 0, max = VA_Get_Size(self->searchers); i < max; i++) {
-        Searcher *searcher = (Searcher*)VA_Fetch(self->searchers, i);
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->searchers); i < max; i++) {
+        Searcher *searcher = (Searcher*)VA_Fetch(ivars->searchers, i);
         doc_freq += Searcher_Doc_Freq(searcher, field, term);
     }
     return doc_freq;
@@ -122,9 +127,10 @@ S_modify_doc_ids(VArray *match_docs, int32_t base) {
 TopDocs*
 PolySearcher_top_docs(PolySearcher *self, Query *query, uint32_t num_wanted,
                       SortSpec *sort_spec) {
+    PolySearcherIVARS *const ivars = PolySearcher_IVARS(self);
     Schema   *schema      = PolySearcher_Get_Schema(self);
-    VArray   *searchers   = self->searchers;
-    I32Array *starts      = self->starts;
+    VArray   *searchers   = ivars->searchers;
+    I32Array *starts      = ivars->starts;
     HitQueue *hit_q       = sort_spec
                             ? HitQ_new(schema, sort_spec, num_wanted)
                             : HitQ_new(NULL, NULL, num_wanted);
@@ -166,8 +172,9 @@ PolySearcher_top_docs(PolySearcher *self, Query *query, uint32_t num_wanted,
 void
 PolySearcher_collect(PolySearcher *self, Query *query,
                      Collector *collector) {
-    VArray *const searchers = self->searchers;
-    I32Array *starts = self->starts;
+    PolySearcherIVARS *const ivars = PolySearcher_IVARS(self);
+    VArray *const searchers = ivars->searchers;
+    I32Array *starts = ivars->starts;
 
     for (uint32_t i = 0, max = VA_Get_Size(searchers); i < max; i++) {
         int32_t start = I32Arr_Get(starts, i);

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/Query.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/Query.c b/core/Lucy/Search/Query.c
index 05a9106..20243ed 100644
--- a/core/Lucy/Search/Query.c
+++ b/core/Lucy/Search/Query.c
@@ -25,24 +25,24 @@
 
 Query*
 Query_init(Query *self, float boost) {
-    self->boost = boost;
+    Query_IVARS(self)->boost = boost;
     ABSTRACT_CLASS_CHECK(self, QUERY);
     return self;
 }
 
 void
 Query_set_boost(Query *self, float boost) {
-    self->boost = boost;
+    Query_IVARS(self)->boost = boost;
 }
 
 float
 Query_get_boost(Query *self) {
-    return self->boost;
+    return Query_IVARS(self)->boost;
 }
 
 void
 Query_serialize(Query *self, OutStream *outstream) {
-    OutStream_Write_F32(outstream, self->boost);
+    OutStream_Write_F32(outstream, Query_IVARS(self)->boost);
 }
 
 Query*

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/QueryParser.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/QueryParser.c b/core/Lucy/Search/QueryParser.c
index 5a0119b..5c99ce7 100644
--- a/core/Lucy/Search/QueryParser.c
+++ b/core/Lucy/Search/QueryParser.c
@@ -104,48 +104,49 @@ QParser_new(Schema *schema, Analyzer *analyzer, const CharBuf *default_boolop,
 QueryParser*
 QParser_init(QueryParser *self, Schema *schema, Analyzer *analyzer,
              const CharBuf *default_boolop, VArray *fields) {
+    QueryParserIVARS *const ivars = QParser_IVARS(self);
     // Init.
-    self->heed_colons = false;
-    self->lexer       = QueryLexer_new();
+    ivars->heed_colons = false;
+    ivars->lexer       = QueryLexer_new();
 
     // Assign.
-    self->schema         = (Schema*)INCREF(schema);
-    self->analyzer       = (Analyzer*)INCREF(analyzer);
-    self->default_boolop = default_boolop
+    ivars->schema         = (Schema*)INCREF(schema);
+    ivars->analyzer       = (Analyzer*)INCREF(analyzer);
+    ivars->default_boolop = default_boolop
                            ? CB_Clone(default_boolop)
                            : CB_new_from_trusted_utf8("OR", 2);
 
     if (fields) {
-        self->fields = VA_Shallow_Copy(fields);
+        ivars->fields = VA_Shallow_Copy(fields);
         for (uint32_t i = 0, max = VA_Get_Size(fields); i < max; i++) {
             CERTIFY(VA_Fetch(fields, i), CHARBUF);
         }
-        VA_Sort(self->fields, NULL, NULL);
+        VA_Sort(ivars->fields, NULL, NULL);
     }
     else {
         VArray *all_fields = Schema_All_Fields(schema);
         uint32_t num_fields = VA_Get_Size(all_fields);
-        self->fields = VA_new(num_fields);
+        ivars->fields = VA_new(num_fields);
         for (uint32_t i = 0; i < num_fields; i++) {
             CharBuf *field = (CharBuf*)VA_Fetch(all_fields, i);
             FieldType *type = Schema_Fetch_Type(schema, field);
             if (type && FType_Indexed(type)) {
-                VA_Push(self->fields, INCREF(field));
+                VA_Push(ivars->fields, INCREF(field));
             }
         }
         DECREF(all_fields);
     }
-    VA_Sort(self->fields, NULL, NULL);
+    VA_Sort(ivars->fields, NULL, NULL);
 
     // Derive default "occur" from default boolean operator.
-    if (CB_Equals_Str(self->default_boolop, "OR", 2)) {
-        self->default_occur = SHOULD;
+    if (CB_Equals_Str(ivars->default_boolop, "OR", 2)) {
+        ivars->default_occur = SHOULD;
     }
-    else if (CB_Equals_Str(self->default_boolop, "AND", 3)) {
-        self->default_occur = MUST;
+    else if (CB_Equals_Str(ivars->default_boolop, "AND", 3)) {
+        ivars->default_occur = MUST;
     }
     else {
-        THROW(ERR, "Invalid value for default_boolop: %o", self->default_boolop);
+        THROW(ERR, "Invalid value for default_boolop: %o", ivars->default_boolop);
     }
 
     return self;
@@ -153,43 +154,45 @@ QParser_init(QueryParser *self, Schema *schema, Analyzer *analyzer,
 
 void
 QParser_destroy(QueryParser *self) {
-    DECREF(self->schema);
-    DECREF(self->analyzer);
-    DECREF(self->default_boolop);
-    DECREF(self->fields);
-    DECREF(self->lexer);
+    QueryParserIVARS *const ivars = QParser_IVARS(self);
+    DECREF(ivars->schema);
+    DECREF(ivars->analyzer);
+    DECREF(ivars->default_boolop);
+    DECREF(ivars->fields);
+    DECREF(ivars->lexer);
     SUPER_DESTROY(self, QUERYPARSER);
 }
 
 Analyzer*
 QParser_get_analyzer(QueryParser *self) {
-    return self->analyzer;
+    return QParser_IVARS(self)->analyzer;
 }
 
 Schema*
 QParser_get_schema(QueryParser *self) {
-    return self->schema;
+    return QParser_IVARS(self)->schema;
 }
 
 CharBuf*
 QParser_get_default_boolop(QueryParser *self) {
-    return self->default_boolop;
+    return QParser_IVARS(self)->default_boolop;
 }
 
 VArray*
 QParser_get_fields(QueryParser *self) {
-    return self->fields;
+    return QParser_IVARS(self)->fields;
 }
 
 bool
 QParser_heed_colons(QueryParser *self) {
-    return self->heed_colons;
+    return QParser_IVARS(self)->heed_colons;
 }
 
 void
 QParser_set_heed_colons(QueryParser *self, bool heed_colons) {
-    self->heed_colons = heed_colons;
-    QueryLexer_Set_Heed_Colons(self->lexer, heed_colons);
+    QueryParserIVARS *const ivars = QParser_IVARS(self);
+    ivars->heed_colons = heed_colons;
+    QueryLexer_Set_Heed_Colons(ivars->lexer, heed_colons);
 }
 
 
@@ -209,7 +212,8 @@ QParser_parse(QueryParser *self, const CharBuf *query_string) {
 
 Query*
 QParser_tree(QueryParser *self, const CharBuf *query_string) {
-    VArray *elems = QueryLexer_Tokenize(self->lexer, query_string);
+    QueryParserIVARS *const ivars = QParser_IVARS(self);
+    VArray *elems = QueryLexer_Tokenize(ivars->lexer, query_string);
     S_balance_parens(self, elems);
     S_parse_subqueries(self, elems);
     Query *query = S_parse_subquery(self, elems, NULL, false);
@@ -219,6 +223,7 @@ QParser_tree(QueryParser *self, const CharBuf *query_string) {
 
 static void
 S_parse_subqueries(QueryParser *self, VArray *elems) {
+    const int32_t default_occur = QParser_IVARS(self)->default_occur;
     while (1) {
         // Work from the inside out, starting with the leftmost innermost
         // paren group.
@@ -254,7 +259,7 @@ S_parse_subqueries(QueryParser *self, VArray *elems) {
         VArray *sub_elems = VA_Slice(elems, left + 1, right - left - 1);
         Query *subquery = S_parse_subquery(self, sub_elems, field, true);
         ParserElem *new_elem = ParserElem_new(TOKEN_QUERY, (Obj*)subquery);
-        if (self->default_occur == MUST) {
+        if (default_occur == MUST) {
             ParserElem_Require(new_elem);
         }
         DECREF(sub_elems);
@@ -351,6 +356,8 @@ S_balance_parens(QueryParser *self, VArray *elems) {
 static void
 S_compose_inner_queries(QueryParser *self, VArray *elems,
                         CharBuf *default_field) {
+    const int32_t default_occur = QParser_IVARS(self)->default_occur;
+
     // Generate all queries.  Apply any fields.
     for (uint32_t i = VA_Get_Size(elems); i--;) {
         CharBuf *field = default_field;
@@ -371,7 +378,7 @@ S_compose_inner_queries(QueryParser *self, VArray *elems,
             LeafQuery *query = LeafQuery_new(field, text);
             ParserElem *new_elem
                 = ParserElem_new(TOKEN_QUERY, (Obj*)query);
-            if (self->default_occur == MUST) {
+            if (default_occur == MUST) {
                 ParserElem_Require(new_elem);
             }
             VA_Store(elems, i, (Obj*)new_elem);
@@ -445,6 +452,8 @@ S_winnow_boolops(QueryParser *self, VArray *elems) {
 // Apply AND.
 static void
 S_compose_and_queries(QueryParser *self, VArray *elems) {
+    const int32_t default_occur = QParser_IVARS(self)->default_occur;
+
     for (uint32_t i = 0; i + 2 < VA_Get_Size(elems); i++) {
         ParserElem *elem = (ParserElem*)VA_Fetch(elems, i + 1);
         if (ParserElem_Get_Type(elem) == TOKEN_AND) {
@@ -477,7 +486,7 @@ S_compose_and_queries(QueryParser *self, VArray *elems) {
             }
             Query *and_query = QParser_Make_AND_Query(self, children);
             ParserElem_Set_Value(preceding, (Obj*)and_query);
-            if (self->default_occur == MUST) {
+            if (default_occur == MUST) {
                 ParserElem_Require(preceding);
             }
             DECREF(and_query);
@@ -490,6 +499,8 @@ S_compose_and_queries(QueryParser *self, VArray *elems) {
 
 static void
 S_compose_or_queries(QueryParser *self, VArray *elems) {
+    const int32_t default_occur = QParser_IVARS(self)->default_occur;
+
     for (uint32_t i = 0; i + 2 < VA_Get_Size(elems); i++) {
         ParserElem *elem = (ParserElem*)VA_Fetch(elems, i + 1);
         if (ParserElem_Get_Type(elem) == TOKEN_OR) {
@@ -522,7 +533,7 @@ S_compose_or_queries(QueryParser *self, VArray *elems) {
             }
             Query *or_query = QParser_Make_OR_Query(self, children);
             ParserElem_Set_Value(preceding, (Obj*)or_query);
-            if (self->default_occur == MUST) {
+            if (default_occur == MUST) {
                 ParserElem_Require(preceding);
             }
             DECREF(or_query);
@@ -535,13 +546,14 @@ S_compose_or_queries(QueryParser *self, VArray *elems) {
 
 static Query*
 S_compose_subquery(QueryParser *self, VArray *elems, bool enclosed) {
+    const int32_t default_occur = QParser_IVARS(self)->default_occur;
     Query *retval;
 
     if (VA_Get_Size(elems) == 0) {
         // No elems means no query. Maybe the search string was something
         // like 'NOT AND'
         if (enclosed) {
-            retval = self->default_occur == SHOULD
+            retval = default_occur == SHOULD
                      ? QParser_Make_OR_Query(self, NULL)
                      : QParser_Make_AND_Query(self, NULL);
         }
@@ -843,8 +855,9 @@ S_unescape(QueryParser *self, CharBuf *orig, CharBuf *target) {
 
 Query*
 QParser_expand_leaf(QueryParser *self, Query *query) {
+    QueryParserIVARS *const ivars = QParser_IVARS(self);
     LeafQuery     *leaf_query  = (LeafQuery*)query;
-    Schema        *schema      = self->schema;
+    Schema        *schema      = ivars->schema;
     ZombieCharBuf *source_text = ZCB_BLANK();
     bool           is_phrase   = false;
     bool           ambiguous   = false;
@@ -873,15 +886,15 @@ QParser_expand_leaf(QueryParser *self, Query *query) {
         VA_Push(fields, INCREF(LeafQuery_Get_Field(leaf_query)));
     }
     else {
-        fields = (VArray*)INCREF(self->fields);
+        fields = (VArray*)INCREF(ivars->fields);
     }
 
     CharBuf *unescaped = CB_new(ZCB_Get_Size(source_text));
     VArray  *queries   = VA_new(VA_Get_Size(fields));
     for (uint32_t i = 0, max = VA_Get_Size(fields); i < max; i++) {
         CharBuf  *field    = (CharBuf*)VA_Fetch(fields, i);
-        Analyzer *analyzer = self->analyzer
-                             ? self->analyzer
+        Analyzer *analyzer = ivars->analyzer
+                             ? ivars->analyzer
                              : Schema_Fetch_Analyzer(schema, field);
 
         if (!analyzer) {

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/RangeMatcher.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/RangeMatcher.c b/core/Lucy/Search/RangeMatcher.c
index 811a19b..7e1c094 100644
--- a/core/Lucy/Search/RangeMatcher.c
+++ b/core/Lucy/Search/RangeMatcher.c
@@ -32,15 +32,16 @@ RangeMatcher*
 RangeMatcher_init(RangeMatcher *self, int32_t lower_bound, int32_t upper_bound,
                   SortCache *sort_cache, int32_t doc_max) {
     Matcher_init((Matcher*)self);
+    RangeMatcherIVARS *const ivars = RangeMatcher_IVARS(self);
 
     // Init.
-    self->doc_id       = 0;
+    ivars->doc_id       = 0;
 
     // Assign.
-    self->lower_bound  = lower_bound;
-    self->upper_bound  = upper_bound;
-    self->sort_cache   = (SortCache*)INCREF(sort_cache);
-    self->doc_max      = doc_max;
+    ivars->lower_bound  = lower_bound;
+    ivars->upper_bound  = upper_bound;
+    ivars->sort_cache   = (SortCache*)INCREF(sort_cache);
+    ivars->doc_max      = doc_max;
 
     // Derive.
 
@@ -49,15 +50,17 @@ RangeMatcher_init(RangeMatcher *self, int32_t lower_bound, int32_t upper_bound,
 
 void
 RangeMatcher_destroy(RangeMatcher *self) {
-    DECREF(self->sort_cache);
+    RangeMatcherIVARS *const ivars = RangeMatcher_IVARS(self);
+    DECREF(ivars->sort_cache);
     SUPER_DESTROY(self, RANGEMATCHER);
 }
 
 int32_t
 RangeMatcher_next(RangeMatcher* self) {
+    RangeMatcherIVARS *const ivars = RangeMatcher_IVARS(self);
     while (1) {
-        if (++self->doc_id > self->doc_max) {
-            self->doc_id--;
+        if (++ivars->doc_id > ivars->doc_max) {
+            ivars->doc_id--;
             return 0;
         }
         else {
@@ -65,18 +68,18 @@ RangeMatcher_next(RangeMatcher* self) {
             // TODO: Unroll? i.e. use SortCache_Get_Ords at constructor time
             // and save ourselves some method call overhead.
             const int32_t ord
-                = SortCache_Ordinal(self->sort_cache, self->doc_id);
-            if (ord >= self->lower_bound && ord <= self->upper_bound) {
+                = SortCache_Ordinal(ivars->sort_cache, ivars->doc_id);
+            if (ord >= ivars->lower_bound && ord <= ivars->upper_bound) {
                 break;
             }
         }
     }
-    return self->doc_id;
+    return ivars->doc_id;
 }
 
 int32_t
 RangeMatcher_advance(RangeMatcher* self, int32_t target) {
-    self->doc_id = target - 1;
+    RangeMatcher_IVARS(self)->doc_id = target - 1;
     return RangeMatcher_next(self);
 }
 
@@ -88,7 +91,7 @@ RangeMatcher_score(RangeMatcher* self) {
 
 int32_t
 RangeMatcher_get_doc_id(RangeMatcher* self) {
-    return self->doc_id;
+    return RangeMatcher_IVARS(self)->doc_id;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/RangeQuery.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/RangeQuery.c b/core/Lucy/Search/RangeQuery.c
index 4349daf..3f7ff15 100644
--- a/core/Lucy/Search/RangeQuery.c
+++ b/core/Lucy/Search/RangeQuery.c
@@ -52,11 +52,12 @@ RangeQuery*
 RangeQuery_init(RangeQuery *self, const CharBuf *field, Obj *lower_term,
                 Obj *upper_term, bool include_lower, bool include_upper) {
     Query_init((Query*)self, 0.0f);
-    self->field          = CB_Clone(field);
-    self->lower_term     = lower_term ? Obj_Clone(lower_term) : NULL;
-    self->upper_term     = upper_term ? Obj_Clone(upper_term) : NULL;
-    self->include_lower  = include_lower;
-    self->include_upper  = include_upper;
+    RangeQueryIVARS *const ivars = RangeQuery_IVARS(self);
+    ivars->field          = CB_Clone(field);
+    ivars->lower_term     = lower_term ? Obj_Clone(lower_term) : NULL;
+    ivars->upper_term     = upper_term ? Obj_Clone(upper_term) : NULL;
+    ivars->include_lower  = include_lower;
+    ivars->include_upper  = include_upper;
     if (!upper_term && !lower_term) {
         DECREF(self);
         self = NULL;
@@ -67,45 +68,48 @@ RangeQuery_init(RangeQuery *self, const CharBuf *field, Obj *lower_term,
 
 void
 RangeQuery_destroy(RangeQuery *self) {
-    DECREF(self->field);
-    DECREF(self->lower_term);
-    DECREF(self->upper_term);
+    RangeQueryIVARS *const ivars = RangeQuery_IVARS(self);
+    DECREF(ivars->field);
+    DECREF(ivars->lower_term);
+    DECREF(ivars->upper_term);
     SUPER_DESTROY(self, RANGEQUERY);
 }
 
 bool
 RangeQuery_equals(RangeQuery *self, Obj *other) {
-    RangeQuery *twin = (RangeQuery*)other;
-    if (twin == self)                               { return true; }
-    if (!Obj_Is_A(other, RANGEQUERY))               { return false; }
-    if (self->boost != twin->boost)                 { return false; }
-    if (!CB_Equals(self->field, (Obj*)twin->field)) { return false; }
-    if (self->lower_term && !twin->lower_term)      { return false; }
-    if (self->upper_term && !twin->upper_term)      { return false; }
-    if (!self->lower_term && twin->lower_term)      { return false; }
-    if (!self->upper_term && twin->upper_term)      { return false; }
-    if (self->lower_term
-        && !Obj_Equals(self->lower_term, twin->lower_term)) { return false; }
-    if (self->upper_term
-        && !Obj_Equals(self->upper_term, twin->upper_term)) { return false; }
-    if (self->include_lower != twin->include_lower)         { return false; }
-    if (self->include_upper != twin->include_upper)         { return false; }
+    if ((RangeQuery*)other == self)                   { return true; }
+    if (!Obj_Is_A(other, RANGEQUERY))                 { return false; }
+    RangeQueryIVARS *const ivars = RangeQuery_IVARS(self);
+    RangeQueryIVARS *const ovars = RangeQuery_IVARS((RangeQuery*)other);
+    if (ivars->boost != ovars->boost)                 { return false; }
+    if (!CB_Equals(ivars->field, (Obj*)ovars->field)) { return false; }
+    if (ivars->lower_term && !ovars->lower_term)      { return false; }
+    if (ivars->upper_term && !ovars->upper_term)      { return false; }
+    if (!ivars->lower_term && ovars->lower_term)      { return false; }
+    if (!ivars->upper_term && ovars->upper_term)      { return false; }
+    if (ivars->lower_term
+        && !Obj_Equals(ivars->lower_term, ovars->lower_term)) { return false; }
+    if (ivars->upper_term
+        && !Obj_Equals(ivars->upper_term, ovars->upper_term)) { return false; }
+    if (ivars->include_lower != ovars->include_lower)         { return false; }
+    if (ivars->include_upper != ovars->include_upper)         { return false; }
     return true;
 }
 
 CharBuf*
 RangeQuery_to_string(RangeQuery *self) {
-    CharBuf *lower_term_str = self->lower_term
-                              ? Obj_To_String(self->lower_term)
+    RangeQueryIVARS *const ivars = RangeQuery_IVARS(self);
+    CharBuf *lower_term_str = ivars->lower_term
+                              ? Obj_To_String(ivars->lower_term)
                               : CB_new_from_trusted_utf8("*", 1);
-    CharBuf *upper_term_str = self->upper_term
-                              ? Obj_To_String(self->upper_term)
+    CharBuf *upper_term_str = ivars->upper_term
+                              ? Obj_To_String(ivars->upper_term)
                               : CB_new_from_trusted_utf8("*", 1);
-    CharBuf *retval = CB_newf("%o:%s%o TO %o%s", self->field,
-                              self->include_lower ? "[" : "{",
+    CharBuf *retval = CB_newf("%o:%s%o TO %o%s", ivars->field,
+                              ivars->include_lower ? "[" : "{",
                               lower_term_str,
                               upper_term_str,
-                              self->include_upper ? "]" : "}"
+                              ivars->include_upper ? "]" : "}"
                              );
     DECREF(upper_term_str);
     DECREF(lower_term_str);
@@ -114,24 +118,25 @@ RangeQuery_to_string(RangeQuery *self) {
 
 void
 RangeQuery_serialize(RangeQuery *self, OutStream *outstream) {
-    OutStream_Write_F32(outstream, self->boost);
-    Freezer_serialize_charbuf(self->field, outstream);
-    if (self->lower_term) {
+    RangeQueryIVARS *const ivars = RangeQuery_IVARS(self);
+    OutStream_Write_F32(outstream, ivars->boost);
+    Freezer_serialize_charbuf(ivars->field, outstream);
+    if (ivars->lower_term) {
         OutStream_Write_U8(outstream, true);
-        FREEZE(self->lower_term, outstream);
+        FREEZE(ivars->lower_term, outstream);
     }
     else {
         OutStream_Write_U8(outstream, false);
     }
-    if (self->upper_term) {
+    if (ivars->upper_term) {
         OutStream_Write_U8(outstream, true);
-        FREEZE(self->upper_term, outstream);
+        FREEZE(ivars->upper_term, outstream);
     }
     else {
         OutStream_Write_U8(outstream, false);
     }
-    OutStream_Write_U8(outstream, self->include_lower);
-    OutStream_Write_U8(outstream, self->include_upper);
+    OutStream_Write_U8(outstream, ivars->include_lower);
+    OutStream_Write_U8(outstream, ivars->include_upper);
 }
 
 RangeQuery*
@@ -184,11 +189,12 @@ RangeCompiler_init(RangeCompiler *self, RangeQuery *parent,
 Matcher*
 RangeCompiler_make_matcher(RangeCompiler *self, SegReader *reader,
                            bool need_score) {
-    RangeQuery *parent = (RangeQuery*)self->parent;
+    RangeQuery *parent = (RangeQuery*)RangeCompiler_IVARS(self)->parent;
+    const CharBuf *field = RangeQuery_IVARS(parent)->field;
     SortReader *sort_reader
         = (SortReader*)SegReader_Fetch(reader, VTable_Get_Name(SORTREADER));
     SortCache *sort_cache = sort_reader
-                            ? SortReader_Fetch_Sort_Cache(sort_reader, parent->field)
+                            ? SortReader_Fetch_Sort_Cache(sort_reader, field)
                             : NULL;
     UNUSED_VAR(need_score);
 
@@ -212,8 +218,8 @@ RangeCompiler_make_matcher(RangeCompiler *self, SegReader *reader,
 
 static int32_t
 S_find_lower_bound(RangeCompiler *self, SortCache *sort_cache) {
-    RangeQuery *parent      = (RangeQuery*)self->parent;
-    Obj        *lower_term  = parent->lower_term;
+    RangeQuery *parent      = (RangeQuery*)RangeCompiler_IVARS(self)->parent;
+    Obj        *lower_term  = RangeQuery_IVARS(parent)->lower_term;
     int32_t     lower_bound = 0;
 
     if (lower_term) {
@@ -230,7 +236,7 @@ S_find_lower_bound(RangeCompiler *self, SortCache *sort_cache) {
                                  : Obj_Equals(lower_term, low_found);
 
             lower_bound = low_ord;
-            if (!exact_match || !parent->include_lower) {
+            if (!exact_match || !RangeQuery_IVARS(parent)->include_lower) {
                 lower_bound++;
             }
             DECREF(value);
@@ -242,8 +248,8 @@ S_find_lower_bound(RangeCompiler *self, SortCache *sort_cache) {
 
 static int32_t
 S_find_upper_bound(RangeCompiler *self, SortCache *sort_cache) {
-    RangeQuery *parent     = (RangeQuery*)self->parent;
-    Obj        *upper_term = parent->upper_term;
+    RangeQuery *parent     = (RangeQuery*)RangeCompiler_IVARS(self)->parent;
+    Obj        *upper_term = RangeQuery_IVARS(parent)->upper_term;
     int32_t     retval     = INT32_MAX;
 
     if (upper_term) {
@@ -260,7 +266,7 @@ S_find_upper_bound(RangeCompiler *self, SortCache *sort_cache) {
                                  : Obj_Equals(upper_term, (Obj*)hi_found);
 
             retval = hi_ord;
-            if (exact_match && !parent->include_upper) {
+            if (exact_match && !RangeQuery_IVARS(parent)->include_upper) {
                 retval--;
             }
             DECREF(value);

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/RequiredOptionalMatcher.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/RequiredOptionalMatcher.c b/core/Lucy/Search/RequiredOptionalMatcher.c
index bf38f19..c419aa3 100644
--- a/core/Lucy/Search/RequiredOptionalMatcher.c
+++ b/core/Lucy/Search/RequiredOptionalMatcher.c
@@ -36,13 +36,14 @@ ReqOptMatcher_init(RequiredOptionalMatcher *self, Similarity *similarity,
     VA_Push(children, INCREF(required_matcher));
     VA_Push(children, INCREF(optional_matcher));
     PolyMatcher_init((PolyMatcher*)self, children, similarity);
+    RequiredOptionalMatcherIVARS *const ivars = ReqOptMatcher_IVARS(self);
 
     // Assign.
-    self->req_matcher       = (Matcher*)INCREF(required_matcher);
-    self->opt_matcher       = (Matcher*)INCREF(optional_matcher);
+    ivars->req_matcher      = (Matcher*)INCREF(required_matcher);
+    ivars->opt_matcher      = (Matcher*)INCREF(optional_matcher);
 
     // Init.
-    self->opt_matcher_first_time = true;
+    ivars->opt_matcher_first_time = true;
 
     DECREF(children);
     return self;
@@ -50,63 +51,68 @@ ReqOptMatcher_init(RequiredOptionalMatcher *self, Similarity *similarity,
 
 void
 ReqOptMatcher_destroy(RequiredOptionalMatcher *self) {
-    DECREF(self->req_matcher);
-    DECREF(self->opt_matcher);
+    RequiredOptionalMatcherIVARS *const ivars = ReqOptMatcher_IVARS(self);
+    DECREF(ivars->req_matcher);
+    DECREF(ivars->opt_matcher);
     SUPER_DESTROY(self, REQUIREDOPTIONALMATCHER);
 }
 
 int32_t
 ReqOptMatcher_next(RequiredOptionalMatcher *self) {
-    return Matcher_Next(self->req_matcher);
+    RequiredOptionalMatcherIVARS *const ivars = ReqOptMatcher_IVARS(self);
+    return Matcher_Next(ivars->req_matcher);
 }
 
 int32_t
 ReqOptMatcher_advance(RequiredOptionalMatcher *self, int32_t target) {
-    return Matcher_Advance(self->req_matcher, target);
+    RequiredOptionalMatcherIVARS *const ivars = ReqOptMatcher_IVARS(self);
+    return Matcher_Advance(ivars->req_matcher, target);
 }
 
 int32_t
 ReqOptMatcher_get_doc_id(RequiredOptionalMatcher *self) {
-    return Matcher_Get_Doc_ID(self->req_matcher);
+    RequiredOptionalMatcherIVARS *const ivars = ReqOptMatcher_IVARS(self);
+    return Matcher_Get_Doc_ID(ivars->req_matcher);
 }
 
 float
 ReqOptMatcher_score(RequiredOptionalMatcher *self) {
-    int32_t const current_doc = Matcher_Get_Doc_ID(self->req_matcher);
-
-    if (self->opt_matcher_first_time) {
-        self->opt_matcher_first_time = false;
-        if (self->opt_matcher != NULL
-            && !Matcher_Advance(self->opt_matcher, current_doc)) {
-            DECREF(self->opt_matcher);
-            self->opt_matcher = NULL;
+    RequiredOptionalMatcherIVARS *const ivars = ReqOptMatcher_IVARS(self);
+    int32_t const current_doc = Matcher_Get_Doc_ID(ivars->req_matcher);
+
+    if (ivars->opt_matcher_first_time) {
+        ivars->opt_matcher_first_time = false;
+        if (ivars->opt_matcher != NULL
+            && !Matcher_Advance(ivars->opt_matcher, current_doc)) {
+            DECREF(ivars->opt_matcher);
+            ivars->opt_matcher = NULL;
         }
     }
 
-    if (self->opt_matcher == NULL) {
-        return Matcher_Score(self->req_matcher) * self->coord_factors[1];
+    if (ivars->opt_matcher == NULL) {
+        return Matcher_Score(ivars->req_matcher) * ivars->coord_factors[1];
     }
     else {
-        int32_t opt_matcher_doc = Matcher_Get_Doc_ID(self->opt_matcher);
+        int32_t opt_matcher_doc = Matcher_Get_Doc_ID(ivars->opt_matcher);
 
         if (opt_matcher_doc < current_doc) {
-            opt_matcher_doc = Matcher_Advance(self->opt_matcher, current_doc);
+            opt_matcher_doc = Matcher_Advance(ivars->opt_matcher, current_doc);
             if (!opt_matcher_doc) {
-                DECREF(self->opt_matcher);
-                self->opt_matcher = NULL;
-                float req_score = Matcher_Score(self->req_matcher);
-                return req_score * self->coord_factors[1];
+                DECREF(ivars->opt_matcher);
+                ivars->opt_matcher = NULL;
+                float req_score = Matcher_Score(ivars->req_matcher);
+                return req_score * ivars->coord_factors[1];
             }
         }
 
         if (opt_matcher_doc == current_doc) {
-            float score = Matcher_Score(self->req_matcher)
-                          + Matcher_Score(self->opt_matcher);
-            score *= self->coord_factors[2];
+            float score = Matcher_Score(ivars->req_matcher)
+                          + Matcher_Score(ivars->opt_matcher);
+            score *= ivars->coord_factors[2];
             return score;
         }
         else {
-            return Matcher_Score(self->req_matcher) * self->coord_factors[1];
+            return Matcher_Score(ivars->req_matcher) * ivars->coord_factors[1];
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/RequiredOptionalQuery.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/RequiredOptionalQuery.c b/core/Lucy/Search/RequiredOptionalQuery.c
index 9a03123..2103755 100644
--- a/core/Lucy/Search/RequiredOptionalQuery.c
+++ b/core/Lucy/Search/RequiredOptionalQuery.c
@@ -36,37 +36,43 @@ RequiredOptionalQuery*
 ReqOptQuery_init(RequiredOptionalQuery *self, Query *required_query,
                  Query *optional_query) {
     PolyQuery_init((PolyQuery*)self, NULL);
-    VA_Push(self->children, INCREF(required_query));
-    VA_Push(self->children, INCREF(optional_query));
+    RequiredOptionalQueryIVARS *const ivars = ReqOptQuery_IVARS(self);
+    VA_Push(ivars->children, INCREF(required_query));
+    VA_Push(ivars->children, INCREF(optional_query));
     return self;
 }
 
 Query*
 ReqOptQuery_get_required_query(RequiredOptionalQuery *self) {
-    return (Query*)VA_Fetch(self->children, 0);
+    RequiredOptionalQueryIVARS *const ivars = ReqOptQuery_IVARS(self);
+    return (Query*)VA_Fetch(ivars->children, 0);
 }
 
 void
 ReqOptQuery_set_required_query(RequiredOptionalQuery *self,
                                Query *required_query) {
-    VA_Store(self->children, 0, INCREF(required_query));
+    RequiredOptionalQueryIVARS *const ivars = ReqOptQuery_IVARS(self);
+    VA_Store(ivars->children, 0, INCREF(required_query));
 }
 
 Query*
 ReqOptQuery_get_optional_query(RequiredOptionalQuery *self) {
-    return (Query*)VA_Fetch(self->children, 1);
+    RequiredOptionalQueryIVARS *const ivars = ReqOptQuery_IVARS(self);
+    return (Query*)VA_Fetch(ivars->children, 1);
 }
 
 void
 ReqOptQuery_set_optional_query(RequiredOptionalQuery *self,
                                Query *optional_query) {
-    VA_Store(self->children, 1, INCREF(optional_query));
+    RequiredOptionalQueryIVARS *const ivars = ReqOptQuery_IVARS(self);
+    VA_Store(ivars->children, 1, INCREF(optional_query));
 }
 
 CharBuf*
 ReqOptQuery_to_string(RequiredOptionalQuery *self) {
-    CharBuf *req_string = Obj_To_String(VA_Fetch(self->children, 0));
-    CharBuf *opt_string = Obj_To_String(VA_Fetch(self->children, 1));
+    RequiredOptionalQueryIVARS *const ivars = ReqOptQuery_IVARS(self);
+    CharBuf *req_string = Obj_To_String(VA_Fetch(ivars->children, 0));
+    CharBuf *opt_string = Obj_To_String(VA_Fetch(ivars->children, 1));
     CharBuf *retval = CB_newf("(+%o %o)", req_string, opt_string);
     DECREF(opt_string);
     DECREF(req_string);
@@ -114,10 +120,11 @@ ReqOptCompiler_init(RequiredOptionalCompiler *self,
 Matcher*
 ReqOptCompiler_make_matcher(RequiredOptionalCompiler *self, SegReader *reader,
                             bool need_score) {
+    RequiredOptionalCompilerIVARS *const ivars = ReqOptCompiler_IVARS(self);
     Schema     *schema       = SegReader_Get_Schema(reader);
     Similarity *sim          = Schema_Get_Similarity(schema);
-    Compiler   *req_compiler = (Compiler*)VA_Fetch(self->children, 0);
-    Compiler   *opt_compiler = (Compiler*)VA_Fetch(self->children, 1);
+    Compiler   *req_compiler = (Compiler*)VA_Fetch(ivars->children, 0);
+    Compiler   *opt_compiler = (Compiler*)VA_Fetch(ivars->children, 1);
     Matcher *req_matcher
         = Compiler_Make_Matcher(req_compiler, reader, need_score);
     Matcher *opt_matcher

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/Searcher.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/Searcher.c b/core/Lucy/Search/Searcher.c
index 11089b6..8d71631 100644
--- a/core/Lucy/Search/Searcher.c
+++ b/core/Lucy/Search/Searcher.c
@@ -32,16 +32,18 @@
 
 Searcher*
 Searcher_init(Searcher *self, Schema *schema) {
-    self->schema  = (Schema*)INCREF(schema);
-    self->qparser = NULL;
+    SearcherIVARS *const ivars = Searcher_IVARS(self);
+    ivars->schema  = (Schema*)INCREF(schema);
+    ivars->qparser = NULL;
     ABSTRACT_CLASS_CHECK(self, SEARCHER);
     return self;
 }
 
 void
 Searcher_destroy(Searcher *self) {
-    DECREF(self->schema);
-    DECREF(self->qparser);
+    SearcherIVARS *const ivars = Searcher_IVARS(self);
+    DECREF(ivars->schema);
+    DECREF(ivars->qparser);
     SUPER_DESTROY(self, SEARCHER);
 }
 
@@ -63,6 +65,7 @@ Searcher_hits(Searcher *self, Obj *query, uint32_t offset, uint32_t num_wanted,
 
 Query*
 Searcher_glean_query(Searcher *self, Obj *query) {
+    SearcherIVARS *const ivars = Searcher_IVARS(self);
     Query *real_query = NULL;
 
     if (!query) {
@@ -72,10 +75,10 @@ Searcher_glean_query(Searcher *self, Obj *query) {
         real_query = (Query*)INCREF(query);
     }
     else if (Obj_Is_A(query, CHARBUF)) {
-        if (!self->qparser) {
-            self->qparser = QParser_new(self->schema, NULL, NULL, NULL);
+        if (!ivars->qparser) {
+            ivars->qparser = QParser_new(ivars->schema, NULL, NULL, NULL);
         }
-        real_query = QParser_Parse(self->qparser, (CharBuf*)query);
+        real_query = QParser_Parse(ivars->qparser, (CharBuf*)query);
     }
     else {
         THROW(ERR, "Invalid type for 'query' param: %o",
@@ -87,7 +90,7 @@ Searcher_glean_query(Searcher *self, Obj *query) {
 
 Schema*
 Searcher_get_schema(Searcher *self) {
-    return self->schema;
+    return Searcher_IVARS(self)->schema;
 }
 
 void

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/SeriesMatcher.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/SeriesMatcher.c b/core/Lucy/Search/SeriesMatcher.c
index b1d7e52..d255811 100644
--- a/core/Lucy/Search/SeriesMatcher.c
+++ b/core/Lucy/Search/SeriesMatcher.c
@@ -28,54 +28,58 @@ SeriesMatcher_new(VArray *matchers, I32Array *offsets) {
 SeriesMatcher*
 SeriesMatcher_init(SeriesMatcher *self, VArray *matchers, I32Array *offsets) {
     Matcher_init((Matcher*)self);
+    SeriesMatcherIVARS *const ivars = SeriesMatcher_IVARS(self);
 
     // Init.
-    self->current_matcher = NULL;
-    self->current_offset  = 0;
-    self->next_offset     = 0;
-    self->doc_id          = 0;
-    self->tick            = 0;
+    ivars->current_matcher = NULL;
+    ivars->current_offset  = 0;
+    ivars->next_offset     = 0;
+    ivars->doc_id          = 0;
+    ivars->tick            = 0;
 
     // Assign.
-    self->matchers        = (VArray*)INCREF(matchers);
-    self->offsets         = (I32Array*)INCREF(offsets);
+    ivars->matchers        = (VArray*)INCREF(matchers);
+    ivars->offsets         = (I32Array*)INCREF(offsets);
 
     // Derive.
-    self->num_matchers    = (int32_t)I32Arr_Get_Size(offsets);
+    ivars->num_matchers    = (int32_t)I32Arr_Get_Size(offsets);
 
     return self;
 }
 
 void
 SeriesMatcher_destroy(SeriesMatcher *self) {
-    DECREF(self->matchers);
-    DECREF(self->offsets);
+    SeriesMatcherIVARS *const ivars = SeriesMatcher_IVARS(self);
+    DECREF(ivars->matchers);
+    DECREF(ivars->offsets);
     SUPER_DESTROY(self, SERIESMATCHER);
 }
 
 int32_t
 SeriesMatcher_next(SeriesMatcher *self) {
-    return SeriesMatcher_advance(self, self->doc_id + 1);
+    SeriesMatcherIVARS *const ivars = SeriesMatcher_IVARS(self);
+    return SeriesMatcher_advance(self, ivars->doc_id + 1);
 }
 
 int32_t
 SeriesMatcher_advance(SeriesMatcher *self, int32_t target) {
-    if (target >= self->next_offset) {
+    SeriesMatcherIVARS *const ivars = SeriesMatcher_IVARS(self);
+    if (target >= ivars->next_offset) {
         // Proceed to next matcher or bail.
-        if (self->tick < self->num_matchers) {
+        if (ivars->tick < ivars->num_matchers) {
             while (1) {
                 uint32_t next_offset
-                    = self->tick + 1 == self->num_matchers
+                    = ivars->tick + 1 == ivars->num_matchers
                       ? INT32_MAX
-                      : I32Arr_Get(self->offsets, self->tick + 1);
-                self->current_matcher = (Matcher*)VA_Fetch(self->matchers,
-                                                           self->tick);
-                self->current_offset = self->next_offset;
-                self->next_offset = next_offset;
-                self->doc_id = next_offset - 1;
-                self->tick++;
-                if (self->current_matcher != NULL
-                    || self->tick >= self->num_matchers
+                      : I32Arr_Get(ivars->offsets, ivars->tick + 1);
+                ivars->current_matcher = (Matcher*)VA_Fetch(ivars->matchers,
+                                                           ivars->tick);
+                ivars->current_offset = ivars->next_offset;
+                ivars->next_offset = next_offset;
+                ivars->doc_id = next_offset - 1;
+                ivars->tick++;
+                if (ivars->current_matcher != NULL
+                    || ivars->tick >= ivars->num_matchers
                    ) {
                     break;
                 }
@@ -84,28 +88,28 @@ SeriesMatcher_advance(SeriesMatcher *self, int32_t target) {
         }
         else {
             // We're done.
-            self->doc_id = 0;
+            ivars->doc_id = 0;
             return 0;
         }
     }
     else {
-        int32_t target_minus_offset = target - self->current_offset;
+        int32_t target_minus_offset = target - ivars->current_offset;
         int32_t found
-            = Matcher_Advance(self->current_matcher, target_minus_offset);
+            = Matcher_Advance(ivars->current_matcher, target_minus_offset);
         if (found) {
-            self->doc_id = found + self->current_offset;
-            return self->doc_id;
+            ivars->doc_id = found + ivars->current_offset;
+            return ivars->doc_id;
         }
         else {
             // Recurse.
-            return SeriesMatcher_advance(self, self->next_offset);
+            return SeriesMatcher_advance(self, ivars->next_offset);
         }
     }
 }
 
 int32_t
 SeriesMatcher_get_doc_id(SeriesMatcher *self) {
-    return self->doc_id;
+    return SeriesMatcher_IVARS(self)->doc_id;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/SortRule.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/SortRule.c b/core/Lucy/Search/SortRule.c
index ee8f2fd..a5758e5 100644
--- a/core/Lucy/Search/SortRule.c
+++ b/core/Lucy/Search/SortRule.c
@@ -35,9 +35,10 @@ SortRule_new(int32_t type, const CharBuf *field, bool reverse) {
 SortRule*
 SortRule_init(SortRule *self, int32_t type, const CharBuf *field,
               bool reverse) {
-    self->field    = field ? CB_Clone(field) : NULL;
-    self->type     = type;
-    self->reverse  = reverse;
+    SortRuleIVARS *ivars = SortRule_IVARS(self);
+    ivars->field    = field ? CB_Clone(field) : NULL;
+    ivars->type     = type;
+    ivars->reverse  = reverse;
 
     // Validate.
     if (type == SortRule_FIELD) {
@@ -54,42 +55,45 @@ SortRule_init(SortRule *self, int32_t type, const CharBuf *field,
 
 void
 SortRule_destroy(SortRule *self) {
-    DECREF(self->field);
+    SortRuleIVARS *ivars = SortRule_IVARS(self);
+    DECREF(ivars->field);
     SUPER_DESTROY(self, SORTRULE);
 }
 
 SortRule*
 SortRule_deserialize(SortRule *self, InStream *instream) {
-    self->type = InStream_Read_C32(instream);
-    if (self->type == SortRule_FIELD) {
-        self->field = Freezer_read_charbuf(instream);
+    SortRuleIVARS *ivars = SortRule_IVARS(self);
+    ivars->type = InStream_Read_C32(instream);
+    if (ivars->type == SortRule_FIELD) {
+        ivars->field = Freezer_read_charbuf(instream);
     }
-    self->reverse = InStream_Read_C32(instream);
+    ivars->reverse = InStream_Read_C32(instream);
     return self;
 }
 
 void
 SortRule_serialize(SortRule *self, OutStream *target) {
-    OutStream_Write_C32(target, self->type);
-    if (self->type == SortRule_FIELD) {
-        Freezer_serialize_charbuf(self->field, target);
+    SortRuleIVARS *ivars = SortRule_IVARS(self);
+    OutStream_Write_C32(target, ivars->type);
+    if (ivars->type == SortRule_FIELD) {
+        Freezer_serialize_charbuf(ivars->field, target);
     }
-    OutStream_Write_C32(target, !!self->reverse);
+    OutStream_Write_C32(target, !!ivars->reverse);
 }
 
 CharBuf*
 SortRule_get_field(SortRule *self) {
-    return self->field;
+    return SortRule_IVARS(self)->field;
 }
 
 int32_t
 SortRule_get_type(SortRule *self) {
-    return self->type;
+    return SortRule_IVARS(self)->type;
 }
 
 bool
 SortRule_get_reverse(SortRule *self) {
-    return self->reverse;
+    return SortRule_IVARS(self)->reverse;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/SortSpec.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/SortSpec.c b/core/Lucy/Search/SortSpec.c
index 9165a27..7d5f523 100644
--- a/core/Lucy/Search/SortSpec.c
+++ b/core/Lucy/Search/SortSpec.c
@@ -35,7 +35,8 @@ SortSpec_new(VArray *rules) {
 
 SortSpec*
 SortSpec_init(SortSpec *self, VArray *rules) {
-    self->rules = VA_Shallow_Copy(rules);
+    SortSpecIVARS *const ivars = SortSpec_IVARS(self);
+    ivars->rules = VA_Shallow_Copy(rules);
     for (int32_t i = 0, max = VA_Get_Size(rules); i < max; i++) {
         SortRule *rule = (SortRule*)VA_Fetch(rules, i);
         CERTIFY(rule, SORTRULE);
@@ -45,7 +46,8 @@ SortSpec_init(SortSpec *self, VArray *rules) {
 
 void
 SortSpec_destroy(SortSpec *self) {
-    DECREF(self->rules);
+    SortSpecIVARS *const ivars = SortSpec_IVARS(self);
+    DECREF(ivars->rules);
     SUPER_DESTROY(self, SORTSPEC);
 }
 
@@ -67,15 +69,16 @@ SortSpec_deserialize(SortSpec *self, InStream *instream) {
 
 VArray*
 SortSpec_get_rules(SortSpec *self) {
-    return self->rules;
+    return SortSpec_IVARS(self)->rules;
 }
 
 void
 SortSpec_serialize(SortSpec *self, OutStream *target) {
-    uint32_t num_rules = VA_Get_Size(self->rules);
+    SortSpecIVARS *const ivars = SortSpec_IVARS(self);
+    uint32_t num_rules = VA_Get_Size(ivars->rules);
     OutStream_Write_C32(target, num_rules);
     for (uint32_t i = 0; i < num_rules; i++) {
-        SortRule *rule = (SortRule*)VA_Fetch(self->rules, i);
+        SortRule *rule = (SortRule*)VA_Fetch(ivars->rules, i);
         SortRule_Serialize(rule, target);
     }
 }

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/Span.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/Span.c b/core/Lucy/Search/Span.c
index f4d65f9..a7b06d9 100644
--- a/core/Lucy/Search/Span.c
+++ b/core/Lucy/Search/Span.c
@@ -28,58 +28,62 @@ Span_new(int32_t offset, int32_t length, float weight) {
 Span*
 Span_init(Span *self, int32_t offset, int32_t length,
           float weight) {
-    self->offset   = offset;
-    self->length   = length;
-    self->weight   = weight;
+    SpanIVARS *const ivars = Span_IVARS(self);
+    ivars->offset   = offset;
+    ivars->length   = length;
+    ivars->weight   = weight;
     return self;
 }
 
 int32_t
 Span_get_offset(Span *self) {
-    return self->offset;
+    return Span_IVARS(self)->offset;
 }
 
 int32_t
 Span_get_length(Span *self) {
-    return self->length;
+    return Span_IVARS(self)->length;
 }
 
 float
 Span_get_weight(Span *self) {
-    return self->weight;
+    return Span_IVARS(self)->weight;
 }
 
 void
 Span_set_offset(Span *self, int32_t offset) {
-    self->offset = offset;
+    Span_IVARS(self)->offset = offset;
 }
 
 void
 Span_set_length(Span *self, int32_t length) {
-    self->length = length;
+    Span_IVARS(self)->length = length;
 }
 
 void
 Span_set_weight(Span *self, float weight) {
-    self->weight = weight;
+    Span_IVARS(self)->weight = weight;
 }
 
 bool
 Span_equals(Span *self, Obj *other) {
-    Span *twin = (Span*)other;
-    if (self == twin)                 { return true; }
+    if (self == (Span*)other)         { return true; }
     if (!Obj_Is_A(other, SPAN))       { return false; }
-    if (self->offset != twin->offset) { return false; }
-    if (self->length != twin->length) { return false; }
-    if (self->weight != twin->weight) { return false; }
+    SpanIVARS *const ivars = Span_IVARS(self);
+    SpanIVARS *const ovars = Span_IVARS((Span*)other);
+    if (ivars->offset != ovars->offset) { return false; }
+    if (ivars->length != ovars->length) { return false; }
+    if (ivars->weight != ovars->weight) { return false; }
     return true;
 }
 
 int32_t
 Span_compare_to(Span *self, Obj *other) {
-    Span *competitor = (Span*)CERTIFY(other, SPAN);
-    int32_t comparison = self->offset - competitor->offset;
-    if (comparison == 0) { comparison = self->length - competitor->length; }
+    CERTIFY(other, SPAN);
+    SpanIVARS *const ivars = Span_IVARS(self);
+    SpanIVARS *const ovars = Span_IVARS((Span*)other);
+    int32_t comparison = ivars->offset - ovars->offset;
+    if (comparison == 0) { comparison = ivars->length - ovars->length; }
     return comparison;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/TermMatcher.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/TermMatcher.c b/core/Lucy/Search/TermMatcher.c
index e5fc865..0d30fd6 100644
--- a/core/Lucy/Search/TermMatcher.c
+++ b/core/Lucy/Search/TermMatcher.c
@@ -27,40 +27,43 @@ TermMatcher*
 TermMatcher_init(TermMatcher *self, Similarity *similarity, PostingList *plist,
                  Compiler *compiler) {
     Matcher_init((Matcher*)self);
+    TermMatcherIVARS *const ivars = TermMatcher_IVARS(self);
 
     // Assign.
-    self->sim           = (Similarity*)INCREF(similarity);
-    self->plist         = (PostingList*)INCREF(plist);
-    self->compiler      = (Compiler*)INCREF(compiler);
-    self->weight        = Compiler_Get_Weight(compiler);
+    ivars->sim           = (Similarity*)INCREF(similarity);
+    ivars->plist         = (PostingList*)INCREF(plist);
+    ivars->compiler      = (Compiler*)INCREF(compiler);
+    ivars->weight        = Compiler_Get_Weight(compiler);
 
     // Init.
-    self->posting        = NULL;
+    ivars->posting        = NULL;
 
     return self;
 }
 
 void
 TermMatcher_destroy(TermMatcher *self) {
-    DECREF(self->sim);
-    DECREF(self->plist);
-    DECREF(self->compiler);
+    TermMatcherIVARS *const ivars = TermMatcher_IVARS(self);
+    DECREF(ivars->sim);
+    DECREF(ivars->plist);
+    DECREF(ivars->compiler);
     SUPER_DESTROY(self, TERMMATCHER);
 }
 
 int32_t
 TermMatcher_next(TermMatcher* self) {
-    PostingList *const plist = self->plist;
+    TermMatcherIVARS *const ivars = TermMatcher_IVARS(self);
+    PostingList *const plist = ivars->plist;
     if (plist) {
         int32_t doc_id = PList_Next(plist);
         if (doc_id) {
-            self->posting = PList_Get_Posting(plist);
+            ivars->posting = PList_Get_Posting(plist);
             return doc_id;
         }
         else {
             // Reclaim resources a little early.
             DECREF(plist);
-            self->plist = NULL;
+            ivars->plist = NULL;
             return 0;
         }
     }
@@ -69,17 +72,18 @@ TermMatcher_next(TermMatcher* self) {
 
 int32_t
 TermMatcher_advance(TermMatcher *self, int32_t target) {
-    PostingList *const plist = self->plist;
+    TermMatcherIVARS *const ivars = TermMatcher_IVARS(self);
+    PostingList *const plist = ivars->plist;
     if (plist) {
         int32_t doc_id = PList_Advance(plist, target);
         if (doc_id) {
-            self->posting = PList_Get_Posting(plist);
+            ivars->posting = PList_Get_Posting(plist);
             return doc_id;
         }
         else {
             // Reclaim resources a little early.
             DECREF(plist);
-            self->plist = NULL;
+            ivars->plist = NULL;
             return 0;
         }
     }
@@ -88,7 +92,8 @@ TermMatcher_advance(TermMatcher *self, int32_t target) {
 
 int32_t
 TermMatcher_get_doc_id(TermMatcher* self) {
-    return Post_Get_Doc_ID(self->posting);
+    TermMatcherIVARS *const ivars = TermMatcher_IVARS(self);
+    return Post_Get_Doc_ID(ivars->posting);
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/TermQuery.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/TermQuery.c b/core/Lucy/Search/TermQuery.c
index e296080..924e13f 100644
--- a/core/Lucy/Search/TermQuery.c
+++ b/core/Lucy/Search/TermQuery.c
@@ -43,58 +43,64 @@ TermQuery_new(const CharBuf *field, const Obj *term) {
 TermQuery*
 TermQuery_init(TermQuery *self, const CharBuf *field, const Obj *term) {
     Query_init((Query*)self, 1.0f);
-    self->field       = CB_Clone(field);
-    self->term        = Obj_Clone(term);
+    TermQueryIVARS *const ivars = TermQuery_IVARS(self);
+    ivars->field  = CB_Clone(field);
+    ivars->term   = Obj_Clone(term);
     return self;
 }
 
 void
 TermQuery_destroy(TermQuery *self) {
-    DECREF(self->field);
-    DECREF(self->term);
+    TermQueryIVARS *const ivars = TermQuery_IVARS(self);
+    DECREF(ivars->field);
+    DECREF(ivars->term);
     SUPER_DESTROY(self, TERMQUERY);
 }
 
 void
 TermQuery_serialize(TermQuery *self, OutStream *outstream) {
-    Freezer_serialize_charbuf(self->field, outstream);
-    FREEZE(self->term, outstream);
-    OutStream_Write_F32(outstream, self->boost);
+    TermQueryIVARS *const ivars = TermQuery_IVARS(self);
+    Freezer_serialize_charbuf(ivars->field, outstream);
+    FREEZE(ivars->term, outstream);
+    OutStream_Write_F32(outstream, ivars->boost);
 }
 
 TermQuery*
 TermQuery_deserialize(TermQuery *self, InStream *instream) {
-    self->field = Freezer_read_charbuf(instream);
-    self->term  = (Obj*)THAW(instream);
-    self->boost = InStream_Read_F32(instream);
+    TermQueryIVARS *const ivars = TermQuery_IVARS(self);
+    ivars->field = Freezer_read_charbuf(instream);
+    ivars->term  = (Obj*)THAW(instream);
+    ivars->boost = InStream_Read_F32(instream);
     return self;
 }
 
 CharBuf*
 TermQuery_get_field(TermQuery *self) {
-    return self->field;
+    return TermQuery_IVARS(self)->field;
 }
 
 Obj*
 TermQuery_get_term(TermQuery *self) {
-    return self->term;
+    return TermQuery_IVARS(self)->term;
 }
 
 bool
 TermQuery_equals(TermQuery *self, Obj *other) {
-    TermQuery *twin = (TermQuery*)other;
-    if (twin == self)                               { return true; }
-    if (!Obj_Is_A(other, TERMQUERY))                { return false; }
-    if (self->boost != twin->boost)                 { return false; }
-    if (!CB_Equals(self->field, (Obj*)twin->field)) { return false; }
-    if (!Obj_Equals(self->term, twin->term))        { return false; }
+    if ((TermQuery*)other == self)                    { return true; }
+    if (!Obj_Is_A(other, TERMQUERY))                  { return false; }
+    TermQueryIVARS *const ivars = TermQuery_IVARS(self);
+    TermQueryIVARS *const ovars = TermQuery_IVARS((TermQuery*)other);
+    if (ivars->boost != ovars->boost)                 { return false; }
+    if (!CB_Equals(ivars->field, (Obj*)ovars->field)) { return false; }
+    if (!Obj_Equals(ivars->term, ovars->term))        { return false; }
     return true;
 }
 
 CharBuf*
 TermQuery_to_string(TermQuery *self) {
-    CharBuf *term_str = Obj_To_String(self->term);
-    CharBuf *retval = CB_newf("%o:%o", self->field, term_str);
+    TermQueryIVARS *const ivars = TermQuery_IVARS(self);
+    CharBuf *term_str = Obj_To_String(ivars->term);
+    CharBuf *retval = CB_newf("%o:%o", ivars->field, term_str);
     DECREF(term_str);
     return retval;
 }
@@ -121,23 +127,24 @@ TermCompiler_new(Query *parent, Searcher *searcher, float boost) {
 TermCompiler*
 TermCompiler_init(TermCompiler *self, Query *parent, Searcher *searcher,
                   float boost) {
+    TermCompilerIVARS *const ivars = TermCompiler_IVARS(self);
+    TermQueryIVARS *const parent_ivars = TermQuery_IVARS((TermQuery*)parent);
     Schema     *schema  = Searcher_Get_Schema(searcher);
-    TermQuery  *tparent = (TermQuery*)parent;
-    Similarity *sim     = Schema_Fetch_Sim(schema, tparent->field);
+    Similarity *sim     = Schema_Fetch_Sim(schema, parent_ivars->field);
 
     // Try harder to get a Similarity if necessary.
     if (!sim) { sim = Schema_Get_Similarity(schema); }
 
     // Init.
     Compiler_init((Compiler*)self, parent, searcher, sim, boost);
-    self->normalized_weight = 0.0f;
-    self->query_norm_factor = 0.0f;
+    ivars->normalized_weight = 0.0f;
+    ivars->query_norm_factor = 0.0f;
 
     // Derive.
     int32_t doc_max  = Searcher_Doc_Max(searcher);
-    int32_t doc_freq = Searcher_Doc_Freq(searcher, tparent->field,
-                                         tparent->term);
-    self->idf = Sim_IDF(sim, doc_freq, doc_max);
+    int32_t doc_freq = Searcher_Doc_Freq(searcher, parent_ivars->field,
+                                         parent_ivars->term);
+    ivars->idf = Sim_IDF(sim, doc_freq, doc_max);
 
     /* The score of any document is approximately equal to:
      *
@@ -150,32 +157,34 @@ TermCompiler_init(TermCompiler *self, Query *parent, Searcher *searcher,
      * tf_d and norm_d can only be added by the Matcher, since they are
      * per-document.
      */
-    self->raw_weight = self->idf * self->boost;
+    ivars->raw_weight = ivars->idf * ivars->boost;
 
     return self;
 }
 
 bool
 TermCompiler_equals(TermCompiler *self, Obj *other) {
-    TermCompiler *twin = (TermCompiler*)other;
-    if (!Compiler_equals((Compiler*)self, other))           { return false; }
-    if (!Obj_Is_A(other, TERMCOMPILER))                     { return false; }
-    if (self->idf != twin->idf)                             { return false; }
-    if (self->raw_weight != twin->raw_weight)               { return false; }
-    if (self->query_norm_factor != twin->query_norm_factor) { return false; }
-    if (self->normalized_weight != twin->normalized_weight) { return false; }
+    if (!Compiler_equals((Compiler*)self, other))             { return false; }
+    if (!Obj_Is_A(other, TERMCOMPILER))                       { return false; }
+    TermCompilerIVARS *const ivars = TermCompiler_IVARS(self);
+    TermCompilerIVARS *const ovars = TermCompiler_IVARS((TermCompiler*)other);
+    if (ivars->idf != ovars->idf)                             { return false; }
+    if (ivars->raw_weight != ovars->raw_weight)               { return false; }
+    if (ivars->query_norm_factor != ovars->query_norm_factor) { return false; }
+    if (ivars->normalized_weight != ovars->normalized_weight) { return false; }
     return true;
 }
 
 void
 TermCompiler_serialize(TermCompiler *self, OutStream *outstream) {
+    TermCompilerIVARS *const ivars = TermCompiler_IVARS(self);
     TermCompiler_Serialize_t super_serialize
         = SUPER_METHOD_PTR(TERMCOMPILER, Lucy_TermCompiler_Serialize);
     super_serialize(self, outstream);
-    OutStream_Write_F32(outstream, self->idf);
-    OutStream_Write_F32(outstream, self->raw_weight);
-    OutStream_Write_F32(outstream, self->query_norm_factor);
-    OutStream_Write_F32(outstream, self->normalized_weight);
+    OutStream_Write_F32(outstream, ivars->idf);
+    OutStream_Write_F32(outstream, ivars->raw_weight);
+    OutStream_Write_F32(outstream, ivars->query_norm_factor);
+    OutStream_Write_F32(outstream, ivars->normalized_weight);
 }
 
 TermCompiler*
@@ -183,21 +192,24 @@ TermCompiler_deserialize(TermCompiler *self, InStream *instream) {
     TermCompiler_Deserialize_t super_deserialize
         = SUPER_METHOD_PTR(TERMCOMPILER, Lucy_TermCompiler_Deserialize);
     self = super_deserialize(self, instream);
-    self->idf               = InStream_Read_F32(instream);
-    self->raw_weight        = InStream_Read_F32(instream);
-    self->query_norm_factor = InStream_Read_F32(instream);
-    self->normalized_weight = InStream_Read_F32(instream);
+    TermCompilerIVARS *const ivars = TermCompiler_IVARS(self);
+    ivars->idf               = InStream_Read_F32(instream);
+    ivars->raw_weight        = InStream_Read_F32(instream);
+    ivars->query_norm_factor = InStream_Read_F32(instream);
+    ivars->normalized_weight = InStream_Read_F32(instream);
     return self;
 }
 
 float
 TermCompiler_sum_of_squared_weights(TermCompiler *self) {
-    return self->raw_weight * self->raw_weight;
+    TermCompilerIVARS *const ivars = TermCompiler_IVARS(self);
+    return ivars->raw_weight * ivars->raw_weight;
 }
 
 void
 TermCompiler_apply_norm_factor(TermCompiler *self, float query_norm_factor) {
-    self->query_norm_factor = query_norm_factor;
+    TermCompilerIVARS *const ivars = TermCompiler_IVARS(self);
+    ivars->query_norm_factor = query_norm_factor;
 
     /* Multiply raw weight by the idf and norm_q factors in this:
      *
@@ -205,24 +217,28 @@ TermCompiler_apply_norm_factor(TermCompiler *self, float query_norm_factor) {
      *
      * Note: factoring in IDF a second time is correct.  See formula.
      */
-    self->normalized_weight
-        = self->raw_weight * self->idf * query_norm_factor;
+    ivars->normalized_weight
+        = ivars->raw_weight * ivars->idf * query_norm_factor;
 }
 
 float
 TermCompiler_get_weight(TermCompiler *self) {
-    return self->normalized_weight;
+    return TermCompiler_IVARS(self)->normalized_weight;
 }
 
 Matcher*
 TermCompiler_make_matcher(TermCompiler *self, SegReader *reader,
                           bool need_score) {
-    TermQuery *tparent = (TermQuery*)self->parent;
+    TermCompilerIVARS *const ivars = TermCompiler_IVARS(self);
+    TermQueryIVARS *const parent_ivars
+        = TermQuery_IVARS((TermQuery*)ivars->parent);
     PostingListReader *plist_reader
         = (PostingListReader*)SegReader_Fetch(
               reader, VTable_Get_Name(POSTINGLISTREADER));
     PostingList *plist = plist_reader
-                         ? PListReader_Posting_List(plist_reader, tparent->field, tparent->term)
+                         ? PListReader_Posting_List(plist_reader,
+                                                    parent_ivars->field,
+                                                    parent_ivars->term)
                          : NULL;
 
     if (plist == NULL || PList_Get_Doc_Freq(plist) == 0) {
@@ -230,7 +246,7 @@ TermCompiler_make_matcher(TermCompiler *self, SegReader *reader,
         return NULL;
     }
     else {
-        Matcher *retval = PList_Make_Matcher(plist, self->sim,
+        Matcher *retval = PList_Make_Matcher(plist, ivars->sim,
                                              (Compiler*)self, need_score);
         DECREF(plist);
         return retval;
@@ -240,16 +256,20 @@ TermCompiler_make_matcher(TermCompiler *self, SegReader *reader,
 VArray*
 TermCompiler_highlight_spans(TermCompiler *self, Searcher *searcher,
                              DocVector *doc_vec, const CharBuf *field) {
-    TermQuery *const  parent = (TermQuery*)self->parent;
-    VArray          *spans   = VA_new(0);
+
+    TermCompilerIVARS *const ivars = TermCompiler_IVARS(self);
+    TermQueryIVARS *const parent_ivars
+        = TermQuery_IVARS((TermQuery*)ivars->parent);
+    VArray *spans = VA_new(0);
     TermVector *term_vector;
     I32Array *starts, *ends;
     UNUSED_VAR(searcher);
 
-    if (!CB_Equals(parent->field, (Obj*)field)) { return spans; }
+    if (!CB_Equals(parent_ivars->field, (Obj*)field)) { return spans; }
 
     // Add all starts and ends.
-    term_vector = DocVec_Term_Vector(doc_vec, field, (CharBuf*)parent->term);
+    term_vector
+        = DocVec_Term_Vector(doc_vec, field, (CharBuf*)parent_ivars->term);
     if (!term_vector) { return spans; }
 
     starts = TV_Get_Start_Offsets(term_vector);

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/TopDocs.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/TopDocs.c b/core/Lucy/Search/TopDocs.c
index d6c770e..fcc68c5 100644
--- a/core/Lucy/Search/TopDocs.c
+++ b/core/Lucy/Search/TopDocs.c
@@ -34,48 +34,53 @@ TopDocs_new(VArray *match_docs, uint32_t total_hits) {
 
 TopDocs*
 TopDocs_init(TopDocs *self, VArray *match_docs, uint32_t total_hits) {
-    self->match_docs = (VArray*)INCREF(match_docs);
-    self->total_hits = total_hits;
+    TopDocsIVARS *const ivars = TopDocs_IVARS(self);
+    ivars->match_docs = (VArray*)INCREF(match_docs);
+    ivars->total_hits = total_hits;
     return self;
 }
 
 void
 TopDocs_destroy(TopDocs *self) {
-    DECREF(self->match_docs);
+    TopDocsIVARS *const ivars = TopDocs_IVARS(self);
+    DECREF(ivars->match_docs);
     SUPER_DESTROY(self, TOPDOCS);
 }
 
 void
 TopDocs_serialize(TopDocs *self, OutStream *outstream) {
-    Freezer_serialize_varray(self->match_docs, outstream);
-    OutStream_Write_C32(outstream, self->total_hits);
+    TopDocsIVARS *const ivars = TopDocs_IVARS(self);
+    Freezer_serialize_varray(ivars->match_docs, outstream);
+    OutStream_Write_C32(outstream, ivars->total_hits);
 }
 
 TopDocs*
 TopDocs_deserialize(TopDocs *self, InStream *instream) {
-    self->match_docs = Freezer_read_varray(instream);
-    self->total_hits = InStream_Read_C32(instream);
+    TopDocsIVARS *const ivars = TopDocs_IVARS(self);
+    ivars->match_docs = Freezer_read_varray(instream);
+    ivars->total_hits = InStream_Read_C32(instream);
     return self;
 }
 
 VArray*
 TopDocs_get_match_docs(TopDocs *self) {
-    return self->match_docs;
+    return TopDocs_IVARS(self)->match_docs;
 }
 
 uint32_t
 TopDocs_get_total_hits(TopDocs *self) {
-    return self->total_hits;
+    return TopDocs_IVARS(self)->total_hits;
 }
 
 void
 TopDocs_set_match_docs(TopDocs *self, VArray *match_docs) {
-    DECREF(self->match_docs);
-    self->match_docs = (VArray*)INCREF(match_docs);
+    TopDocsIVARS *const ivars = TopDocs_IVARS(self);
+    DECREF(ivars->match_docs);
+    ivars->match_docs = (VArray*)INCREF(match_docs);
 }
 void
 TopDocs_set_total_hits(TopDocs *self, uint32_t total_hits) {
-    self->total_hits = total_hits;
+    TopDocs_IVARS(self)->total_hits = total_hits;
 }