check in changes for tag support
authorbdemsky <bdemsky>
Wed, 9 May 2007 17:36:07 +0000 (17:36 +0000)
committerbdemsky <bdemsky>
Wed, 9 May 2007 17:36:07 +0000 (17:36 +0000)
14 files changed:
Robust/src/ClassLibrary/Object.java
Robust/src/IR/Flat/BuildCode.java
Robust/src/IR/Tree/BuildIR.java
Robust/src/IR/TypeUtil.java
Robust/src/Main/Main.java
Robust/src/README
Robust/src/Runtime/GenericHashtable.c
Robust/src/Runtime/GenericHashtable.h
Robust/src/Runtime/Queue.c
Robust/src/Runtime/Queue.h
Robust/src/Runtime/SimpleHash.h
Robust/src/Runtime/garbage.c
Robust/src/Runtime/runtime.c
Robust/src/Runtime/runtime.h

index a972bfd23cb1d90cdf7617b0bbce38af0af3abad..6fbd8047f4b24f4f44d55f697a1e99aeb175d54d 100644 (file)
@@ -3,6 +3,9 @@ public class Object {
     private int cachedCode;
     private boolean cachedHash;
 
+    /* DO NOT USE ANY OF THESE - THEY ARE FOR IMPLEMENTING TAGS */
+    private Object tags;
+
     public int hashCode() {
        if (!cachedHash) {
            cachedCode=nativehashCode();
index 5d49ef3b59e543d692b9cebf22b81eb44f80ca37..e744e1f271ad159de73fed929206e2cae2557e36 100644 (file)
@@ -100,6 +100,11 @@ public class BuildCode {
                           (state.getArrayNumber(
                                                 (new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass))).makeArray(state))+state.numClasses()));
 
+       outstructs.println("#define OBJECTARRAYTYPE "+
+                          (state.getArrayNumber(
+                                                (new TypeDescriptor(typeutil.getClass(TypeUtil.ObjectClass))).makeArray(state))+state.numClasses()));
+
+
        outstructs.println("#define STRINGTYPE "+typeutil.getClass(TypeUtil.StringClass).getId());
        outstructs.println("#define CHARARRAYTYPE "+
                           (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.CHAR)).makeArray(state))+state.numClasses()));
@@ -111,9 +116,13 @@ public class BuildCode {
                           (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state).makeArray(state))+state.numClasses()));
        
        outstructs.println("#define NUMCLASSES "+state.numClasses());
-       if (state.TASK)
+       if (state.TASK) {
            outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId());
-
+           outstructs.println("#define TAGTYPE "+typeutil.getClass(TypeUtil.TagClass).getId());
+           outstructs.println("#define TAGARRAYTYPE "+
+                              (state.getArrayNumber(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass)).makeArray(state))+state.numClasses()));
+       }
+       
        // Output the C class declarations
        // These could mutually reference each other
        if (state.THREAD)
@@ -159,6 +168,7 @@ public class BuildCode {
                outtask.println("struct taskdescriptor {");
                outtask.println("void * taskptr;");
                outtask.println("int numParameters;");
+               outtask.println("int numTotal;");
                outtask.println("struct parameterdescriptor **descriptorarray;");
                outtask.println("char * name;");
                outtask.println("};");
@@ -459,6 +469,8 @@ public class BuildCode {
        output.println("struct taskdescriptor task_"+task.getSafeSymbol()+"={");
        output.println("&"+task.getSafeSymbol()+",");
        output.println("/* number of parameters */" +task.numParameters() + ",");
+       int numtotal=task.numParameters()+fm.numTags();
+       output.println("/* number total parameters */" +numtotal + ",");
        output.println("parameterdescriptors_"+task.getSafeSymbol()+",");
        output.println("\""+task.getSymbol()+"\"");
        output.println("};");
@@ -875,7 +887,7 @@ public class BuildCode {
                }
                for(int i=0;i<fm.numTags();i++) {
                    TempDescriptor temp=fm.getTag(i);
-                   output.println("  struct TagDescriptor * "+temp.getSafeSymbol()+";");
+                   output.println("  struct ___TagDescriptor___ * "+temp.getSafeSymbol()+";");
                }
 
                output.println("};\n");
@@ -1441,7 +1453,7 @@ public class BuildCode {
            for(int i=0;i<fm.numTags();i++) {
                TempDescriptor temp=fm.getTag(i);
                int offset=i+objectparams.numPrimitives();
-               output.println("struct TagDescriptor * "+temp.getSafeSymbol()+"=parameterarray["+offset+"];");
+               output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+"=parameterarray["+offset+"];");
            }
 
            if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
@@ -1451,6 +1463,27 @@ public class BuildCode {
     
     public void generateFlatFlagActionNode(FlatMethod fm, FlatFlagActionNode ffan, PrintWriter output) {
        output.println("/* FlatFlagActionNode */");
+
+
+       /* Process tag changes */
+       Relation tagsettable=new Relation();
+       Relation tagcleartable=new Relation();
+
+       Iterator tagsit=ffan.getTempTagPairs(); 
+       while (tagsit.hasNext()) {
+           TempTagPair ttp=(TempTagPair) tagsit.next();
+           TempDescriptor objtmp=ttp.getTemp();
+           TagDescriptor tag=ttp.getTag();
+           TempDescriptor tagtmp=ttp.getTagTemp();
+           boolean tagstatus=ffan.getTagChange(ttp);
+           if (tagstatus) {
+               tagsettable.put(objtmp, tagtmp);
+           } else {
+               tagcleartable.put(objtmp, tagtmp);
+           }
+       }
+
+
        Hashtable flagandtable=new Hashtable();
        Hashtable flagortable=new Hashtable();
 
@@ -1489,11 +1522,47 @@ public class BuildCode {
            }
        }
 
-       Iterator orit=flagortable.keySet().iterator();
-       while(orit.hasNext()) {
-           TempDescriptor temp=(TempDescriptor)orit.next();
-           int ormask=((Integer)flagortable.get(temp)).intValue();
+
+       HashSet flagtagset=new HashSet();
+       flagtagset.addAll(flagortable.keySet());
+       flagtagset.addAll(flagandtable.keySet());
+       flagtagset.addAll(tagsettable.keySet());
+       flagtagset.addAll(tagcleartable.keySet());
+
+       Iterator ftit=flagtagset.iterator();
+       while(ftit.hasNext()) {
+           TempDescriptor temp=(TempDescriptor)ftit.next();
+           
+           
+           Set tagtmps=tagcleartable.get(temp);
+           if (tagtmps!=null) {
+               Iterator tagit=tagtmps.iterator();
+               while(tagit.hasNext()) {
+                   TempDescriptor tagtmp=(TempDescriptor)tagit.next();
+                   if (GENERATEPRECISEGC) 
+                       output.println("tagclear(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
+                   else
+                       output.println("tagclear((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
+               }
+           }
+
+           tagtmps=tagsettable.get(temp);
+           if (tagtmps!=null) {
+               Iterator tagit=tagtmps.iterator();
+               while(tagit.hasNext()) {
+                   TempDescriptor tagtmp=(TempDescriptor)tagit.next();
+                   if (GENERATEPRECISEGC)
+                       output.println("tagset(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
+                   else
+                       output.println("tagset((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
+               }
+           }
+
+           int ormask=0;
            int andmask=0xFFFFFFF;
+           
+           if (flagortable.containsKey(temp))
+               ormask=((Integer)flagortable.get(temp)).intValue();
            if (flagandtable.containsKey(temp))
                andmask=((Integer)flagandtable.get(temp)).intValue();
            if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
@@ -1502,56 +1571,5 @@ public class BuildCode {
                output.println("flagorand("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
            }
        }
-       Iterator andit=flagandtable.keySet().iterator();
-       while(andit.hasNext()) {
-           TempDescriptor temp=(TempDescriptor)andit.next();
-           int andmask=((Integer)flagandtable.get(temp)).intValue();
-           if (!flagortable.containsKey(temp)) {
-               if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT)
-                   output.println("flagorandinit("+generateTemp(fm, temp)+", 0, 0x"+Integer.toHexString(andmask)+");");
-               else
-                   output.println("flagorand("+generateTemp(fm, temp)+", 0, 0x"+Integer.toHexString(andmask)+");");
-           }
-       }
-
-       /* Process tag changes */
-       Relation tagsettable=new Relation();
-       Relation tagcleartable=new Relation();
-
-       Iterator tagsit=ffan.getTempTagPairs(); 
-       while (tagsit.hasNext()) {
-           TempTagPair ttp=(TempTagPair) tagsit.next();
-           TempDescriptor objtmp=ttp.getTemp();
-           TagDescriptor tag=ttp.getTag();
-           TempDescriptor tagtmp=ttp.getTagTemp();
-           boolean tagstatus=ffan.getTagChange(ttp);
-           if (tagstatus) {
-               tagsettable.put(objtmp, tagtmp);
-           } else {
-               tagcleartable.put(objtmp, tagtmp);
-           }
-       }
-
-       Iterator clearit=tagcleartable.keySet().iterator();
-       while(clearit.hasNext()) {
-           TempDescriptor objtmp=(TempDescriptor)clearit.next();
-           Set tagtmps=tagcleartable.get(objtmp);
-           Iterator tagit=tagtmps.iterator();
-           while(tagit.hasNext()) {
-               TempDescriptor tagtmp=(TempDescriptor)tagit.next();
-               output.println("tagclear("+generateTemp(fm, objtmp)+", "+generateTemp(fm,tagtmp)+");");
-           }
-       }
-
-       Iterator setit=tagsettable.keySet().iterator();
-       while(setit.hasNext()) {
-           TempDescriptor objtmp=(TempDescriptor)setit.next();
-           Set tagtmps=tagcleartable.get(objtmp);
-           Iterator tagit=tagtmps.iterator();
-           while(tagit.hasNext()) {
-               TempDescriptor tagtmp=(TempDescriptor)tagit.next();
-               output.println("tagset("+generateTemp(fm, objtmp)+", "+generateTemp(fm,tagtmp)+");");
-           }
-       }
     }
 }
index bfcf62a760e92896199b3c829a967e75a16b5028..d82d0350b99f72e5ce0ee603c678ff9dcfdb40df 100644 (file)
@@ -209,7 +209,8 @@ public class BuildIR {
            NameDescriptor nd=parseName(snn);
            cn.setSuper(nd.toString());
        } else {
-           if (!cn.getSymbol().equals(TypeUtil.ObjectClass))
+           if (!(cn.getSymbol().equals(TypeUtil.ObjectClass)||
+                 cn.getSymbol().equals(TypeUtil.TagClass)))
                cn.setSuper(TypeUtil.ObjectClass);
        }
        cn.setModifiers(parseModifiersList(pn.getChild("modifiers")));
index 9e09427e342f29694140e4d719ba6c9eb7cf2d9e..7c67d49ebe42987d284bebe060b3ad68b3369f68 100644 (file)
@@ -5,6 +5,7 @@ public class TypeUtil {
     public static final String StringClass="String";
     public static final String ObjectClass="Object";
     public static final String StartupClass="StartupObject";
+    public static final String TagClass="TagDescriptor";
     State state;
     Hashtable supertable;
     Hashtable subclasstable;
index b0ee390dcb68f369f3d7aa9ce0cebfb580483a85..16ae718187bc98b01cd4ef796df4de4b7f2fffb8 100644 (file)
@@ -80,7 +80,7 @@ public class Main {
          readSourceFile(state, ClassLibraryPrefix+"ObjectJava.java");
       } else {
          readSourceFile(state, ClassLibraryPrefix+"Object.java");
-         //      readSourceFile(state, ClassLibraryPrefix+"TagDescriptor.java");
+         readSourceFile(state, ClassLibraryPrefix+"TagDescriptor.java");
       }
 
       if (state.TASK) {
index 8b709157b57ee00d7515b2151a28b47b442d8c34..55b172314624598055a005f5fc2bafbdab382800 100644 (file)
@@ -1,54 +1 @@
-I. Compiling a simple test program
-
-1) Go to the Robust directory and type "cvs update"
-
-2) Go into the src directory and build the compiler by typing:
-make clean
-make
-
-3) To run the compiler on a source file (For example to compile
-Tests/Array.java):
-java -cp ../cup/:. Main.Main -mainclass Array Tests/Array.java
-NOTE: The mainclass option specifies the class that contains the main method
-
-4) To compiler and link the output of the compiler do:
-gcc -IRuntime -I. -O0 -g methods.c Runtime/runtime.c
-
-5) To run the binary type:
-./a.out
-
-
-
-II. Command line options
-
-To see all the legal command line options for the compiler type:
-java -cp ../cup:. Main.Main -help
-
-
-
-III. Using Garbage Collection 
-(DEPRECATED...THIS IS FOR CONSERVATIVE GC ONLY...WE NOW HAVE PRECISE GC.)
-
-
-1) Download the Hans Boehm garbage collector
-
-2) Make a directory called gc in the Runtime directory & untar the gc into this directory
-
-3) ./configure --prefix={RUNTIME DIRECTORY}; make;make install to build
-(Modify the prefix to the appropriate path for the runtime directory.
-
-4) Make sure the gc libraries are placed in Runtime/lib and the include files in Runtime/include
-
-5) Change step 4 in the build procedure to:
-gcc -IRuntime -I. -IRuntime/include -DBOEHM_GC -LRuntime/lib/ -lgc -O9 -g methods.c Runtime/runtime.c
-
-IV. High level organization of the compiler:
-1. Lexer is in src/Lex
-2. Parser is built from the grammar in Parse/java14.cup
-3. Internal Representations are in the the IR subdirectory
-3a. Tree representation is in IR/Tree (constructed by IR/Tree/BuildTree)
-3b. Flattened representation in is IR/Flat (constructed by IR/Flat/BuildFlat)
-4. Code is generated from the flattened representation by IR/Flat/BuildCode
-5. Main/Main.java is the top level
-6. ClassLibrary contains the class library
-7. Runtime contains the runtime
\ No newline at end of file
+See the wiki page at http://demsky.eecs.uci.edu/compiler/
\ No newline at end of file
index 2742cc266437ddd906ada979b8850e153be68747..ac50f964979dce195e97ae9e3152170f67d8e539 100755 (executable)
 #include "dmalloc.h"
 #endif
 
+void * getfirstkey(struct genhashtable *ht) {
+  return ht->list->src;
+}
+
 int genputtable(struct genhashtable *ht, void * key, void * object) {
   unsigned int bin=genhashfunction(ht,key);
   struct genpointerlist * newptrlist=(struct genpointerlist *) RUNMALLOC(sizeof(struct genpointerlist));
index 3a65a4c48fa1c6d3cf3a71e245598e9eb6e7ac1e..951f044cc07882672ddc3973db544b99cd889cc2 100755 (executable)
@@ -32,6 +32,7 @@ struct geniterator {
 };
 
 struct genhashtable * genallocatehashtable(unsigned int (*hash_function)(void *),int (*comp_function)(void *,void *));
+void * getfirstkey(struct genhashtable *ht);
 void genfreehashtable(struct genhashtable * ht);
 void genrehash(struct genhashtable * ht);
 void * getnext(struct genhashtable *,void *);
index a29e96b083116d37f9de2149b66a01f4f009b56d..5a8da1fa9157c9017707b64724604935bf918d2c 100644 (file)
@@ -8,6 +8,10 @@ struct Queue * createQueue() {
   return RUNMALLOC(sizeof(struct Queue));
 }
 
+void freeQueue(struct Queue * q) {
+  RUNFREE(q);
+}
+
 int isEmpty(struct Queue *queue) {
   return queue->head==NULL;
 }
@@ -27,6 +31,16 @@ struct QueueItem * addNewItem(struct Queue * queue, void * ptr) {
   return item;
 }
 
+struct QueueItem * findItem(struct Queue * queue, void *ptr) {
+  struct QueueItem * item=queue->head;
+  while(item!=NULL) {
+    if (item->objectptr==ptr)
+      return item;
+    item=item->next;
+  }
+  return NULL;
+}
+
 void removeItem(struct Queue * queue, struct QueueItem * item) {
   struct QueueItem * prev=item->prev;
   struct QueueItem * next=item->next;
index 6e9f63dc7716c63179821857ebb5cef7e610ec9b..ef25820db1857a8f5e54ad96bbcd85760af2d0da 100644 (file)
@@ -13,8 +13,10 @@ struct QueueItem {
   struct QueueItem * prev;
 };
 
+void freeQueue(struct Queue * q);
 struct Queue * createQueue();
 struct QueueItem * addNewItem(struct Queue * queue, void * ptr);
+struct QueueItem * findItem(struct Queue * queue, void * ptr);
 void removeItem(struct Queue * queue, struct QueueItem * item);
 int isEmpty(struct Queue *queue);
 struct QueueItem * getTail(struct Queue * queue);
index 3d89d6e2d5f1f2fa1d893f386d8d145581dd28c7..2a25d6ccc730764adcc43bc57bf553e8dd76cde1 100755 (executable)
@@ -60,7 +60,7 @@ struct RuntimeNode {
 };
 
 struct RuntimeIterator {
-  struct RuntimeNode *cur, *tail;
+  struct RuntimeNode *cur;
 };
 
 inline struct RuntimeIterator * noargallocateRuntimeIterator();
index 69f32a6a35ea3ac74dded56795ff868cd29099ee..8dc7d5feeb7c989d6602a533f2e1a9dcbdd4e791 100644 (file)
@@ -21,7 +21,7 @@
 #define HEAPSIZE(x,y) (((int)((x)/0.6))+y)
 
 #ifdef TASK
-extern struct Queue * activetasks;
+extern struct genhashtable * activetasks;
 extern struct parameterwrapper * objectqueues[NUMCLASSES];
 extern struct genhashtable * failedtasks;
 extern struct taskparamdescriptor *currtpd;
@@ -208,22 +208,24 @@ void collect(struct garbagelist * stackptr) {
 
   }
 
-  {
     /* Update active tasks */
-    struct QueueItem * ptr=activetasks->head;
-    while (ptr!=NULL) {
-      struct taskparamdescriptor *tpd=ptr->objectptr;
+  {
+    struct genpointerlist * ptr=activetasks->list;
+    while(ptr!=NULL) {
+      struct taskparamdescriptor *tpd=ptr->src;
       int i;
       for(i=0;i<tpd->numParameters;i++) {
-       void *orig=tpd->parameterArray[i];
-       void *copy;
+       void * orig=tpd->parameterArray[i];
+       void * copy;
        if (gc_createcopy(orig, &copy))
          enqueue(orig);
        tpd->parameterArray[i]=copy;
       }
-      ptr=ptr->next;
+      ptr=ptr->inext;
     }
+    genrehash(activetasks);
   }
+
     /* Update failed tasks */
   {
     struct genpointerlist * ptr=failedtasks->list;
index b905affb9ec58912620b5254432a7f5df4de474f..0c5b4c5c394378ca07454c7f0bc817baab4a4bd9 100644 (file)
 #include<stdio.h>
 #include "option.h"
 
+#define ARRAYSET(array, type, index, value) \
+((type *)(&(& array->___length___)[1]))[index]=value
+
+#define ARRAYGET(array, type, index) \
+((type *)(&(& array->___length___)[1]))[index]
+
 extern int classsize[];
 jmp_buf error_handler;
 int instructioncount;
@@ -40,7 +46,7 @@ int instaccum=0;
 #include "instrument.h"
 #endif
 
-struct Queue * activetasks;
+struct genhashtable * activetasks;
 struct parameterwrapper * objectqueues[NUMCLASSES];
 struct genhashtable * failedtasks;
 struct taskparamdescriptor * currtpd;
@@ -61,8 +67,10 @@ int main(int argc, char **argv) {
   failedtasks=genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd, 
                                   (int (*)(void *,void *)) &comparetpd);
   /* Create queue of active tasks */
-  activetasks=createQueue();
-  
+  activetasks=genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd, 
+                                  (int (*)(void *,void *)) &comparetpd);
+
+
   /* Process task information */
   processtasks();
 
@@ -119,10 +127,207 @@ int comparetpd(struct taskparamdescriptor *ftd1, struct taskparamdescriptor *ftd
   return 1;
 }
 
+#define TAGARRAYINTERVAL 10
+#define OBJECTARRAYINTERVAL 10
+
+/* This function sets a tag. */
+#ifdef PRECISE_GC
+void tagset(void *ptr, struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
+#else
+void tagset(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
+#endif
+  struct ___Object___ * tagptr=obj->___tags___;
+  if (tagptr==NULL) {
+    obj->___tags___=(struct ___Object___ *)tagd;
+  } else {
+    /* Have to check if it is already set */
+    if (tagptr->type==TAGTYPE) {
+      struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
+      if (td==tagd)
+       return;
+#ifdef PRECISE_GC
+      int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
+      struct ArrayObject * ao=allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
+      obj=(struct ___Object___ *)ptrarray[2];
+      tagd=(struct ___TagDescriptor___ *)ptrarray[3];
+      td=(struct ___TagDescriptor___ *) obj->___tags___;
+#else
+      struct ArrayObject * ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
+#endif
+      ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
+      ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
+      obj->___tags___=(struct ___Object___ *) ao;
+      ao->___cachedCode___=2;
+    } else {
+      /* Array Case */
+      int i;
+      struct ArrayObject *ao=(struct ArrayObject *) tagptr;
+      for(i=0;i<ao->___cachedCode___;i++) {
+       struct ___TagDescriptor___ * td=ARRAYGET(ao, struct ___TagDescriptor___*, i);
+       if (td==tagd)
+         return;
+      }
+      if (ao->___cachedCode___<ao->___length___) {
+       ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
+       ao->___cachedCode___++;
+      } else {
+#ifdef PRECISE_GC
+       int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
+       struct ArrayObject * aonew=allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
+       obj=(struct ___Object___ *)ptrarray[2];
+       tagd=(struct ___TagDescriptor___ *) ptrarray[3];
+       ao=(struct ArrayObject *)obj->___tags___;
+#else
+       struct ArrayObject * aonew=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
+#endif
+       aonew->___cachedCode___=ao->___length___+1;
+       for(i=0;i<ao->___length___;i++) {
+         ARRAYSET(aonew, struct ___TagDescriptor___*, i, ARRAYGET(ao, struct ___TagDescriptor___*, i));
+       }
+       ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
+      }
+    }
+  }
+
+  {
+    struct ___Object___ * tagset=tagd->___tagset___;
+    
+    if(tagset==NULL) {
+      tagd->___tagset___=obj;
+    } else if (tagset->type!=OBJECTARRAYTYPE) {
+#ifdef PRECISE_GC
+      int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
+      struct ArrayObject * ao=allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
+      obj=(struct ___Object___ *)ptrarray[2];
+      tagd=(struct ___TagDescriptor___ *)ptrarray[3];
+#else
+      struct ArrayObject * ao=allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
+#endif
+      ARRAYSET(ao, struct ___Object___ *, 0, tagd->___tagset___);
+      ARRAYSET(ao, struct ___Object___ *, 1, obj);
+      ao->___cachedCode___=2;
+      tagd->___tagset___=(struct ___Object___ *)ao;
+    } else {
+      struct ArrayObject *ao=(struct ArrayObject *) tagset;
+      if (ao->___cachedCode___<ao->___length___) {
+       ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
+      } else {
+       int i;
+#ifdef PRECISE_GC
+       int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
+       struct ArrayObject * aonew=allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
+       obj=(struct ___Object___ *)ptrarray[2];
+       tagd=(struct ___TagDescriptor___ *)ptrarray[3];
+       ao=(struct ArrayObject *)tagd->___tagset___;
+#else
+       struct ArrayObject * aonew=allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
+#endif
+       aonew->___cachedCode___=ao->___cachedCode___+1;
+       for(i=0;i<ao->___length___;i++) {
+         ARRAYSET(aonew, struct ___Object___*, i, ARRAYGET(ao, struct ___Object___*, i));
+       }
+       ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
+       tagd->___tagset___=(struct ___Object___ *) ao;
+      }
+    }
+  }
+}
+
+/* This function clears a tag. */
+#ifdef PRECISE_GC
+void tagclear(void *ptr, struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
+#else
+void tagclear(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
+#endif
+  /* We'll assume that tag is alway there.
+     Need to statically check for this of course. */
+  struct ___Object___ * tagptr=obj->___tags___;
+
+  if (tagptr->type==TAGTYPE) {
+    if ((struct ___TagDescriptor___ *)tagptr==tagd)
+      obj->___tags___=NULL;
+    else
+      printf("ERROR 1 in tagclear\n");
+  } else {
+    struct ArrayObject *ao=(struct ArrayObject *) tagptr;
+    int i;
+    for(i=0;i<ao->___cachedCode___;i++) {
+      struct ___TagDescriptor___ * td=ARRAYGET(ao, struct ___TagDescriptor___ *, i);
+      if (td==tagd) {
+       ao->___cachedCode___--;
+       if (i<ao->___cachedCode___)
+         ARRAYSET(ao, struct ___TagDescriptor___ *, i, ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
+       ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
+       if (ao->___cachedCode___==0)
+         obj->___tags___=NULL;
+       goto PROCESSCLEAR;
+      }
+    }
+    printf("ERROR 2 in tagclear\n");
+  }
+ PROCESSCLEAR:
+  {
+    struct ___Object___ *tagset=tagd->___tagset___;
+    if (tagset->type!=OBJECTARRAYTYPE) {
+      if (tagset==obj)
+       tagd->___tagset___=NULL;
+      else
+       printf("ERROR 3 in tagclear\n");
+    } else {
+      struct ArrayObject *ao=(struct ArrayObject *) tagset;
+      int i;
+      for(i=0;i<ao->___cachedCode___;i++) {
+       struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
+       if (tobj==obj) {
+         ao->___cachedCode___--;
+         if (i<ao->___cachedCode___)
+           ARRAYSET(ao, struct ___Object___ *, i, ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
+         ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
+         if (ao->___cachedCode___==0)
+           tagd->___tagset___=NULL;
+         goto ENDCLEAR;
+       }
+      }
+      printf("ERROR 4 in tagclear\n");
+    }
+  }
+ ENDCLEAR:
+  return;
+  
+}
+/* This function allocates a new tag. */
+#ifdef PRECISE_GC
+struct ___TagDescriptor___ * allocate_tag(void *ptr, int index) {
+  struct ___TagDescriptor___ * v=(struct ___TagDescriptor___ *) mygcmalloc((struct garbagelist *) ptr, classsize[STARTUPTYPE]);
+#else
+struct ___TagDescriptor___ * allocate_tag(int index) {
+  struct ___TagDescriptor___ * v=FREEMALLOC(classsize[STARTUPTYPE]);
+#endif
+  v->type=STARTUPTYPE;
+  v->flag=index;
+  return v;
+} 
+
+
+
 /* This function updates the flag for object ptr.  It or's the flag
    with the or mask and and's it with the andmask. */
 
+void flagbody(struct ___Object___ *ptr, int flag);
+
 void flagorand(void * ptr, int ormask, int andmask) {
+  int oldflag=((int *)ptr)[1];
+  int flag=ormask|oldflag;
+  flag&=andmask;
+  // Not sure why this was necessary
+  //  if (flag==oldflag) /* Don't do anything */
+  //  return;
+  //else 
+  flagbody(ptr, flag);
+}
+
+void intflagorand(void * ptr, int ormask, int andmask) {
   int oldflag=((int *)ptr)[1];
   int flag=ormask|oldflag;
   flag&=andmask;
@@ -138,100 +343,149 @@ void flagorandinit(void * ptr, int ormask, int andmask) {
   flagbody(ptr,flag);
 }
 
-void flagbody(void *ptr, int flag) {
-  struct RuntimeHash *flagptr=(struct RuntimeHash *)(((int*)ptr)[2]);
-  ((int*)ptr)[1]=flag;
-
+void flagbody(struct ___Object___ *ptr, int flag) {
+  struct parameterwrapper *flagptr=(struct parameterwrapper *)ptr->flagptr;
+  ptr->flag=flag;
+  
   /*Remove object from all queues */
   while(flagptr!=NULL) {
-    struct RuntimeHash *next;
-    RuntimeHashget(flagptr, (int) ptr, (int *) &next);
-    RuntimeHashremove(flagptr, (int)ptr, (int) next);
+    struct parameterwrapper *next;
+    struct ___Object___ * tag=ptr->___tags___;
+    RuntimeHashget(flagptr->objectset, (int) ptr, (int *) &next);
+    RuntimeHashremove(flagptr->objectset, (int)ptr, (int) next);
     flagptr=next;
   }
   
   {
     struct QueueItem *tmpptr;
-    struct parameterwrapper * parameter=objectqueues[((int *)ptr)[0]];
+    struct parameterwrapper * parameter=objectqueues[ptr->type];
     int i;
-    struct RuntimeHash * prevptr=NULL;
+    struct parameterwrapper * prevptr=NULL;
+    struct ___Object___ *tagptr=ptr->___tags___;
+      
+    /* Outer loop iterates through all parameter queues an object of
+       this type could be in.  */
+
     while(parameter!=NULL) {
+      /* Check tags */
+      if (parameter->numbertags>0) {
+       if (tagptr==NULL)
+         goto nextloop;
+       else if(tagptr->type==TAGTYPE) {
+         struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
+         for(i=0;i<parameter->numbertags;i++) {
+           //slotid is parameter->tagarray[2*i];
+           int tagid=parameter->tagarray[2*i+1];
+           if (tagid!=tagptr->flag)
+             goto nextloop; /*We don't have this tag */          
+         }
+       } else {
+         struct ArrayObject * ao=(struct ArrayObject *) tagptr;
+         for(i=0;i<parameter->numbertags;i++) {
+           //slotid is parameter->tagarray[2*i];
+           int tagid=parameter->tagarray[2*i+1];
+           int j;
+           for(j=0;j<ao->___cachedCode___;j++) {
+             if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, i)->flag)
+               goto foundtag;
+           }
+           goto nextloop;
+         foundtag:
+           ;
+         }
+       }
+      }
+
+      /* Check flags */
       for(i=0;i<parameter->numberofterms;i++) {
        int andmask=parameter->intarray[i*2];
        int checkmask=parameter->intarray[i*2+1];
        if ((flag&andmask)==checkmask) {
-         RuntimeHashadd(parameter->objectset, (int) ptr, (int) prevptr);
-         prevptr=parameter->objectset;
-         {
-           struct RuntimeIterator iteratorarray[MAXTASKPARAMS];
-           void * taskpointerarray[MAXTASKPARAMS];
-           int j;
-           int numparams=parameter->task->numParameters;
-           int done=1;
-           struct taskdescriptor * task=parameter->task;
-           int newindex=-1;
-           for(j=0;j<numparams;j++) {
-             struct parameterwrapper *pw=(struct parameterwrapper *)task->descriptorarray[j]->queue;
-             if (parameter==pw) {
-               taskpointerarray[j]=ptr;
-               newindex=j;
-             } else {
-               RuntimeHashiterator(pw->objectset, &iteratorarray[j]);
-               if (RunhasNext(&iteratorarray[j])) {
-                 taskpointerarray[j]=(void *) Runkey(&iteratorarray[j]);
-                 Runnext(&iteratorarray[j]);
-               } else {
-                 done=0;
-                 break; /* No tasks to dispatch */
-               }
-             }
-           }
-           /* Queue task items... */
-
-           while(done) {
-             struct taskparamdescriptor *tpd=RUNMALLOC(sizeof(struct taskparamdescriptor));
-             tpd->task=task;
-             tpd->numParameters=numparams;
-             tpd->parameterArray=RUNMALLOC(sizeof(void *)*numparams);
-             for(j=0;j<numparams;j++)
-               tpd->parameterArray[j]=taskpointerarray[j];
-             /* Queue task */
-             if (!gencontains(failedtasks, tpd))
-               addNewItem(activetasks, tpd);
-             else {
-               RUNFREE(tpd->parameterArray);
-               RUNFREE(tpd);
-             }
-
-             /* This loop iterates to the next parameter combination */
-             for(j=0;j<numparams;j++) {
-               if (j==newindex) {
-                 if ((j+1)==numparams)
-                   done=0;
-                 continue;
-               }
-               if (RunhasNext(&iteratorarray[j])) {
-                 taskpointerarray[j]=(void *) Runkey(&iteratorarray[j]);
-                 Runnext(&iteratorarray[j]);
-                 break;
-               } else if ((j+1)!=numparams) {
-                 RuntimeHashiterator(task->descriptorarray[j]->queue, &iteratorarray[j]);
-               } else {
-                 done=0;
-                 break;
-               }
-             }
-           }
-         }
+         enqueuetasks(parameter, prevptr, ptr);
+         prevptr=parameter;
          break;
        }
       }
+    nextloop:
       parameter=parameter->next;
     }
-    ((struct RuntimeHash **)ptr)[2]=prevptr;
+    ptr->flagptr=prevptr;
   }
 }
+  
+void enqueuetasks(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr) {
+  void * taskpointerarray[MAXTASKPARAMS];
+  int j;
+  int numparams=parameter->task->numParameters;
+  int numiterators=parameter->task->numTotal-1;
+
+  struct taskdescriptor * task=parameter->task;
+  
+  RuntimeHashadd(parameter->objectset, (int) ptr, (int) prevptr);
+  
+  /* Add enqueued object to parameter vector */
+  taskpointerarray[parameter->slot]=ptr;
 
+  /* Reset iterators */
+  for(j=0;j<numiterators;j++) {
+    toiReset(&parameter->iterators[j]);
+  }
+
+  /* Find initial state */
+  for(j=0;j<numiterators;j++) {
+  backtrackinit:
+    if(toiHasNext(&parameter->iterators[j], taskpointerarray))
+      toiNext(&parameter->iterators[j], taskpointerarray);
+    else if (j>0) {
+      /* Need to backtrack */
+      toiReset(&parameter->iterators[j]);
+      j--;
+      goto backtrackinit;
+    } else {
+      /* Nothing to enqueue */
+      return;
+    }
+  }
+
+  
+  while(1) {
+    /* Enqueue current state */
+    struct taskparamdescriptor *tpd=RUNMALLOC(sizeof(struct taskparamdescriptor));
+    tpd->task=task;
+    tpd->numParameters=numiterators+1;
+    tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
+    for(j=0;j<=numiterators;j++)
+      tpd->parameterArray[j]=taskpointerarray[j];
+    
+    /* Enqueue task */
+    if (!gencontains(failedtasks, tpd)&&!gencontains(activetasks,tpd)) {
+      genputtable(activetasks, tpd, tpd);
+    } else {
+      RUNFREE(tpd->parameterArray);
+      RUNFREE(tpd);
+    }
+    
+    /* This loop iterates to the next parameter combination */
+    if (numiterators==0)
+      return;
+
+    for(j=numiterators-1; j<numiterators;j++) {
+    backtrackinc:
+      if(toiHasNext(&parameter->iterators[j], taskpointerarray))
+       toiNext(&parameter->iterators[j], taskpointerarray);
+      else if (j>0) {
+       /* Need to backtrack */
+       toiReset(&parameter->iterators[j]);
+       j--;
+       goto backtrackinc;
+      } else {
+       /* Nothing more to enqueue */
+       return;
+      }
+    }
+  }
+}
 /* Handler for signals. The signals catch null pointer errors and
    arithmatic errors. */
 
@@ -292,7 +546,7 @@ void executetasks() {
   mmap(0, 0x1000, 0, MAP_SHARED|MAP_FIXED|MAP_ANON, -1, 0);
 
   newtask:
-  while(!isEmpty(activetasks)||(maxreadfd>0)) {
+  while((hashsize(activetasks)>0)||(maxreadfd>0)) {
 
     /* Check if any filedescriptors have IO pending */
     if (maxreadfd>0) {
@@ -311,7 +565,7 @@ void executetasks() {
            void * objptr;
            //      printf("Setting fd %d\n",fd);
            if (RuntimeHashget(fdtoobject, fd,(int *) &objptr)) {
-             flagorand(objptr,1,0xFFFFFFFF); /* Set the first flag to 1 */
+             intflagorand(objptr,1,0xFFFFFFFF); /* Set the first flag to 1 */
            }
          }
        }
@@ -319,11 +573,10 @@ void executetasks() {
     }
 
     /* See if there are any active tasks */
-    if (!isEmpty(activetasks)) {
+    if (hashsize(activetasks)>0) {
       int i;
-      struct QueueItem * qi=(struct QueueItem *) getTail(activetasks);
-      currtpd=(struct taskparamdescriptor *) qi->objectptr;
-      removeItem(activetasks, qi);
+      currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
+      genfreekey(activetasks, currtpd);
 
       /* Check if this task has failed */
       if (gencontains(failedtasks, currtpd)) {
@@ -332,19 +585,39 @@ void executetasks() {
        RUNFREE(currtpd);
        goto newtask;
       }
-      
+      int numparams=currtpd->task->numParameters;
+      int numtotal=currtpd->task->numTotal;
+
       /* Make sure that the parameters are still in the queues */
-      for(i=0;i<currtpd->task->numParameters;i++) {
+      for(i=0;i<numparams;i++) {
        void * parameter=currtpd->parameterArray[i];
        struct parameterdescriptor * pd=currtpd->task->descriptorarray[i];
        struct parameterwrapper *pw=(struct parameterwrapper *) pd->queue;
+       int j;
+       /* Check that object is still in queue */
        if (!RuntimeHashcontainskey(pw->objectset, (int) parameter)) {
          RUNFREE(currtpd->parameterArray);
          RUNFREE(currtpd);
          goto newtask;
        }
+       /* Check that object still has necessary tags */
+       for(j=0;j<pd->numbertags;j++) {
+         int slotid=pd->tagarray[2*i]+numparams;
+         struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
+         if (!containstag(parameter, tagd)) {
+           RUNFREE(currtpd->parameterArray);
+           RUNFREE(currtpd);
+           goto newtask;
+         }
+       }
+       
        taskpointerarray[i+OFFSET]=parameter;
       }
+      /* Copy the tags */
+      for(;i<numtotal;i++) {
+       taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
+      }
+
       {
        /* Checkpoint the state */
        forward=allocateRuntimeHash(100);
@@ -397,6 +670,100 @@ void executetasks() {
   }
 }
 
+/* This function processes an objects tags */
+void processtags(struct parameterdescriptor *pd, int index, struct parameterwrapper *parameter, int * iteratorcount, int *statusarray, int numparams) {
+  int i;
+
+  for(i=0;i<pd->numbertags;i++) {
+    int slotid=pd->tagarray[2*i];
+    int tagid=pd->tagarray[2*i+1];
+    
+    if (statusarray[slotid+numparams]==0) {
+      parameter->iterators[*iteratorcount].istag=1;
+      parameter->iterators[*iteratorcount].tagid=tagid;
+      parameter->iterators[*iteratorcount].slot=slotid+numparams;
+      parameter->iterators[*iteratorcount].tagobjectslot=index;
+      statusarray[slotid+numparams]=1;
+      (*iteratorcount)++;
+    }
+  }
+}
+
+
+void processobject(struct parameterwrapper *parameter, int index, struct parameterdescriptor *pd, int *iteratorcount, int * statusarray, int numparams) {
+  int i;
+  int tagcount=0;
+  struct RuntimeHash * objectset=((struct parameterwrapper *)pd->queue)->objectset;
+
+  parameter->iterators[*iteratorcount].istag=0;
+  parameter->iterators[*iteratorcount].slot=index;
+  parameter->iterators[*iteratorcount].objectset=objectset;
+  statusarray[index]=1;
+
+  for(i=0;i<pd->numbertags;i++) {
+    int slotid=pd->tagarray[2*i];
+    int tagid=pd->tagarray[2*i+1];
+    if (statusarray[slotid+numparams]!=0) {
+      /* This tag has already been enqueued, use it to narrow search */
+      parameter->iterators[*iteratorcount].tagbindings[tagcount]=slotid+numparams;
+      tagcount++;
+    }
+  }
+  parameter->iterators[*iteratorcount].numtags=tagcount;
+
+  (*iteratorcount)++;
+}
+
+/* This function builds the iterators for a task & parameter */
+
+void builditerators(struct taskdescriptor * task, int index, struct parameterwrapper * parameter) {
+  int statusarray[MAXTASKPARAMS];
+  int i;
+  int numparams=task->numParameters;
+  int iteratorcount=0;
+  for(i=0;i<MAXTASKPARAMS;i++) statusarray[i]=0;
+
+  statusarray[index]=1; /* Initial parameter */
+  /* Process tags for initial iterator */
+  
+  processtags(task->descriptorarray[index], index, parameter, & iteratorcount, statusarray, numparams);
+  
+  while(1) {
+  loopstart:
+    /* Check for objects with existing tags */
+    for(i=0;i<numparams;i++) {
+      if (statusarray[i]==0) {
+       struct parameterdescriptor *pd=task->descriptorarray[i];
+       int j;
+       for(j=0;j<pd->numbertags;j++) {
+         int slotid=pd->tagarray[2*j];
+         if(statusarray[slotid+numparams]!=0) {
+           processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
+           processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
+           goto loopstart;
+         }
+       }
+      }
+    }
+    /* Nothing with a tag enqueued */
+
+    for(i=0;i<numparams;i++) {
+      if (statusarray[i]==0) {
+       struct parameterdescriptor *pd=task->descriptorarray[i];
+       processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
+       processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
+       goto loopstart;
+      }
+    }
+
+    /* Nothing left */
+    return;
+  }
+}
+
+
+
 /* This function processes the task information to create queues for
    each parameter type. */
 
@@ -415,15 +782,147 @@ void processtasks() {
       parameter->objectset=allocateRuntimeHash(10);
       parameter->numberofterms=param->numberterms;
       parameter->intarray=param->intarray;
+      parameter->numbertags=param->numbertags;
+      parameter->tagarray=param->tagarray;
       parameter->task=task;
       /* Link new queue in */
       while((*ptr)!=NULL)
        ptr=&((*ptr)->next);
       (*ptr)=parameter;
     }
+
+    /* Build iterators for parameters */
+    for(j=0;j<task->numParameters;j++) {
+      struct parameterdescriptor *param=task->descriptorarray[j];
+      struct parameterwrapper *parameter=param->queue;      
+      parameter->slot=j;
+      builditerators(task, j, parameter);
+    }
+  }
+}
+
+void toiReset(struct tagobjectiterator * it) {
+  if (it->istag) {
+    it->tagobjindex=0;
+  } else if (it->numtags>0) {
+    it->tagobjindex=0;
+  } else {
+    RuntimeHashiterator(it->objectset, &it->it);
+  }
+}
+
+int toiHasNext(struct tagobjectiterator *it, void ** objectarray) {
+  if (it->istag) {
+    /* Iterate tag */
+    /* Get object with tags */
+    struct ___Object___ *obj=objectarray[it->tagobjectslot];
+    struct ___Object___ *tagptr=obj->___tags___;
+    if (tagptr->type==TAGTYPE) {
+      if ((it->tagobjindex==0)&& /* First object */
+         (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
+       return 1;
+      else
+       return 0;
+    } else {
+      struct ArrayObject *ao=(struct ArrayObject *) tagptr;
+      int tagindex=it->tagobjindex;
+      for(;tagindex<ao->___cachedCode___;tagindex++) {
+       struct ___TagDescriptor___ *td=ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
+       if (td->flag==it->tagid) {
+         it->tagobjindex=tagindex; /* Found right type of tag */
+         return 1;
+       }
+      }
+      return 0;
+    }
+  } else if (it->numtags>0) {
+    /* Use tags to locate appropriate objects */
+    struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
+    struct ___Object___ *objptr=tag->___tagset___;
+    int i;
+    if (objptr->type!=OBJECTARRAYTYPE) {
+      if (it->tagobjindex>0)
+       return 0;
+      if (!RuntimeHashcontainskey(it->objectset, (int) objptr))
+       return 0;
+      for(i=1;i<it->numtags;i++) {
+       struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
+       if (!containstag(objptr,tag2))
+         return 0;
+      }
+      return 1;
+    } else {
+      struct ArrayObject *ao=(struct ArrayObject *) objptr;
+      int tagindex;
+      int i;
+      for(tagindex=it->tagobjindex;tagindex<ao->___cachedCode___;tagindex++) {
+       struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
+       if (!RuntimeHashcontainskey(it->objectset, (int) objptr))
+         continue;
+       for(i=1;i<it->numtags;i++) {
+         struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
+         if (!containstag(objptr,tag2))
+           goto nexttag;
+       }
+       return 1;
+      nexttag:
+       ;
+      }
+      it->tagobjindex=tagindex;
+      return 0;
+    }
+  } else {
+    return RunhasNext(&it->it);
   }
 }
 
+int containstag(struct ___Object___ *ptr, struct ___TagDescriptor___ *tag) {
+  int j;
+  struct ___Object___ * objptr=tag->___tagset___;
+  if (objptr->type==OBJECTARRAYTYPE) {
+    struct ArrayObject *ao=(struct ArrayObject *)objptr;
+    for(j=0;j<ao->___cachedCode___;j++) {
+      if (ptr==ARRAYGET(ao, struct ___Object___*, j))
+       return 1;
+    }
+    return 0;
+  } else
+    return objptr==ptr;
+}
+
+void toiNext(struct tagobjectiterator *it , void ** objectarray) {
+  /* hasNext has all of the intelligence */
+  if(it->istag) {
+    /* Iterate tag */
+    /* Get object with tags */
+    struct ___Object___ *obj=objectarray[it->tagobjectslot];
+    struct ___Object___ *tagptr=obj->___tags___;
+    if (tagptr->type==TAGTYPE) {
+      it->tagobjindex++;
+      objectarray[it->slot]=tagptr;
+    } else {
+      struct ArrayObject *ao=(struct ArrayObject *) tagptr;
+      objectarray[it->slot]=ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
+    }
+  } else if (it->numtags>0) {
+    /* Use tags to locate appropriate objects */
+    struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
+    struct ___Object___ *objptr=tag->___tagset___;
+    if (objptr->type!=OBJECTARRAYTYPE) {
+      it->tagobjindex++;
+      objectarray[it->slot]=objptr;
+    } else {
+      struct ArrayObject *ao=(struct ArrayObject *) objptr;
+      objectarray[it->slot]=ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
+    }
+  } else {
+    /* Iterate object */
+    objectarray[it->slot]=(void *)Runkey(&it->it);
+    Runnext(&it->it);
+  }
+}
+
+
 #endif
 
 void exithandler(int sig, siginfo_t *info, void * uap) {
index 60b656aa7ac9625c0536f461a8f3bac120d75243..844039e642734afce41f58288c4d48ab5130c33c 100644 (file)
@@ -46,18 +46,37 @@ void createstartupobject();
 #ifdef TASK
 #include "SimpleHash.h"
 #include "task.h"
+#include "structdefs.h"
+
 void flagorand(void * ptr, int ormask, int andmask);
 void flagorandinit(void * ptr, int ormask, int andmask);
-void flagbody(void *ptr, int flag);
 void executetasks();
 void processtasks();
 
+struct tagobjectiterator {
+  int istag; /* 0 if object iterator, 1 if tag iterator */
+  struct RuntimeIterator it; /* Object iterator */
+  struct RuntimeHash * objectset;
+  int slot;
+  int tagobjindex; /* Index for tag or object depending on use */
+  /*if tag we have an object binding */
+  int tagid;
+  int tagobjectslot;
+  /*if object, we may have one or more tag bindings */
+  int numtags;
+  int tagbindings[MAXTASKPARAMS-1]; /* list slots */
+};
+
 struct parameterwrapper {
   struct parameterwrapper *next;
   struct RuntimeHash * objectset;
   int numberofterms;
   int * intarray;
+  int numbertags;
+  int * tagarray;
   struct taskdescriptor * task;
+  int slot;
+  struct tagobjectiterator iterators[MAXTASKPARAMS-1];
 };
 
 struct taskparamdescriptor {
@@ -66,13 +85,17 @@ struct taskparamdescriptor {
   void ** parameterArray;
 };
 
-struct tpdlist {
-  struct taskparamdescriptor * task;
-  struct tpdlist * next;
-};
-
 int hashCodetpd(struct taskparamdescriptor *);
 int comparetpd(struct taskparamdescriptor *, struct taskparamdescriptor *);
+
+void toiReset(struct tagobjectiterator * it);
+int toiHasNext(struct tagobjectiterator *it, void ** objectarray);
+void toiNext(struct tagobjectiterator *it , void ** objectarray);
+void processobject(struct parameterwrapper *parameter, int index, struct parameterdescriptor *pd, int *iteratorcount, int * statusarray, int numparams);
+void processtags(struct parameterdescriptor *pd, int index, struct parameterwrapper *parameter, int * iteratorcount, int *statusarray, int numparams);
+void builditerators(struct taskdescriptor * task, int index, struct parameterwrapper * parameter);
+void enqueuetasks(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr);
+
 #endif
 
 #endif