compiler/libec: Attempt to speedup namespace scanning
authorJerome St-Louis <jerome@ecere.com>
Wed, 15 Feb 2012 11:29:29 +0000 (18:29 +0700)
committerJerome St-Louis <jerome@ecere.com>
Wed, 15 Feb 2012 11:38:23 +0000 (18:38 +0700)
compiler/bootstrap/ecere/bootstrap/BTNode.c
compiler/bootstrap/ecere/bootstrap/BinaryTree.c
compiler/libec/src/ast.ec
compiler/libec/src/ecdefs.ec
compiler/libec/src/pass15.ec
ecere/src/com/BTNode.ec
ecere/src/com/BinaryTree.ec

index 0f0b6c4..6ad24d6 100644 (file)
@@ -525,6 +525,42 @@ break;
 return this;
 }
 
+extern int strncmp(const char * , const char * , int n);
+
+struct __ecereNameSpace__ecere__sys__BTNode * __ecereMethod___ecereNameSpace__ecere__sys__BTNode_FindPrefix(struct __ecereNameSpace__ecere__sys__BTNode * this, char * key)
+{
+struct __ecereNameSpace__ecere__sys__BTNode * subString = (((void *)0));
+int len = key ? strlen(key) : 0;
+
+while(this)
+{
+int result;
+
+if(key && this->key)
+result = strcmp(key, (char *)this->key);
+else if(key && !this->key)
+result = 1;
+else if(!key && this->key)
+result = -1;
+else
+result = 0;
+if(result < 0)
+{
+if(!strncmp(key, (char *)this->key, len))
+subString = this;
+this = this->left;
+}
+else if(result > 0)
+this = this->right;
+else
+{
+subString = this;
+break;
+}
+}
+return subString;
+}
+
 struct __ecereNameSpace__ecere__sys__BTNode * __ecereMethod___ecereNameSpace__ecere__sys__BTNode_FindAll(struct __ecereNameSpace__ecere__sys__BTNode * this, unsigned int key)
 {
 struct __ecereNameSpace__ecere__sys__BTNode * result = (((void *)0));
@@ -1065,6 +1101,7 @@ if(((struct __ecereNameSpace__ecere__com__Module *)(((char *)module + 12)))->app
 __ecereClass___ecereNameSpace__ecere__sys__BTNode = class;
 __ecereNameSpace__ecere__com__eClass_AddMethod(class, "OnSerialize", 0, __ecereMethod___ecereNameSpace__ecere__sys__BTNode_OnSerialize, 1);
 __ecereNameSpace__ecere__com__eClass_AddMethod(class, "OnUnserialize", 0, __ecereMethod___ecereNameSpace__ecere__sys__BTNode_OnUnserialize, 1);
+__ecereNameSpace__ecere__com__eClass_AddMethod(class, "FindPrefix", "ecere::sys::BTNode FindPrefix(char * key)", __ecereMethod___ecereNameSpace__ecere__sys__BTNode_FindPrefix, 1);
 __ecereNameSpace__ecere__com__eClass_AddMethod(class, "FindString", "ecere::sys::BTNode FindString(char * key)", __ecereMethod___ecereNameSpace__ecere__sys__BTNode_FindString, 1);
 __ecereNameSpace__ecere__com__eClass_AddDataMember(class, "key", "uint", 4, 4, 1);
 __ecereNameSpace__ecere__com__eClass_AddDataMember(class, "parent", "ecere::sys::BTNode", 4, 4, 1);
index ebf714c..9748d28 100644 (file)
@@ -332,6 +332,13 @@ struct __ecereNameSpace__ecere__sys__BTNode * __ecereMethod___ecereNameSpace__ec
 return this->root ? __ecereMethod___ecereNameSpace__ecere__sys__BTNode_FindString(this->root, key) : (((void *)0));
 }
 
+struct __ecereNameSpace__ecere__sys__BTNode * __ecereMethod___ecereNameSpace__ecere__sys__BTNode_FindPrefix(struct __ecereNameSpace__ecere__sys__BTNode * this, char *  key);
+
+struct __ecereNameSpace__ecere__sys__BTNode * __ecereMethod___ecereNameSpace__ecere__sys__BinaryTree_FindPrefix(struct __ecereNameSpace__ecere__sys__BinaryTree * this, char * key)
+{
+return this->root ? __ecereMethod___ecereNameSpace__ecere__sys__BTNode_FindPrefix(this->root, key) : (((void *)0));
+}
+
 struct __ecereNameSpace__ecere__sys__BTNode * __ecereMethod___ecereNameSpace__ecere__sys__BTNode_FindAll(struct __ecereNameSpace__ecere__sys__BTNode * this, unsigned int key);
 
 struct __ecereNameSpace__ecere__sys__BTNode * __ecereMethod___ecereNameSpace__ecere__sys__BinaryTree_FindAll(struct __ecereNameSpace__ecere__sys__BinaryTree * this, unsigned int key)
@@ -483,6 +490,7 @@ __ecereNameSpace__ecere__com__eClass_AddMethod(class, "CompareString", "int Comp
 __ecereNameSpace__ecere__com__eClass_AddMethod(class, "Delete", "void Delete(ecere::sys::BTNode node)", __ecereMethod___ecereNameSpace__ecere__sys__BinaryTree_Delete, 1);
 __ecereNameSpace__ecere__com__eClass_AddMethod(class, "Find", "ecere::sys::BTNode Find(unsigned int key)", __ecereMethod___ecereNameSpace__ecere__sys__BinaryTree_Find, 1);
 __ecereNameSpace__ecere__com__eClass_AddMethod(class, "FindAll", "ecere::sys::BTNode FindAll(unsigned int key)", __ecereMethod___ecereNameSpace__ecere__sys__BinaryTree_FindAll, 1);
+__ecereNameSpace__ecere__com__eClass_AddMethod(class, "FindPrefix", "ecere::sys::BTNode FindPrefix(char * key)", __ecereMethod___ecereNameSpace__ecere__sys__BinaryTree_FindPrefix, 1);
 __ecereNameSpace__ecere__com__eClass_AddMethod(class, "FindString", "ecere::sys::BTNode FindString(char * key)", __ecereMethod___ecereNameSpace__ecere__sys__BinaryTree_FindString, 1);
 __ecereNameSpace__ecere__com__eClass_AddMethod(class, "Free", "void Free()", __ecereMethod___ecereNameSpace__ecere__sys__BinaryTree_Free, 1);
 __ecereNameSpace__ecere__com__eClass_AddMethod(class, "FreeString", "void ::FreeString(char * string)", __ecereMethod___ecereNameSpace__ecere__sys__BinaryTree_FreeString, 1);
index 44a552e..22dfcfe 100644 (file)
@@ -411,6 +411,8 @@ Specifier MkEnum(Identifier id, OldList list)
       {
          Symbol symbol { string = CopyString(id.string), isStruct = true, type = type };
          type.refCount++;
+         if(strstr(symbol.string, "::"))
+            curContext.hasNameSpace = true;
          if(!curContext.structSymbols.Add((BTNode)symbol))
             FreeSymbol(symbol);
       }
@@ -418,6 +420,8 @@ Specifier MkEnum(Identifier id, OldList list)
       {
          Symbol symbol { string = CopyString(e.id.string), type = type };
          type.refCount++;
+         if(strstr(symbol.string, "::"))
+            curContext.hasNameSpace = true;
          if(!(curContext.templateTypesOnly ? curContext.parent : curContext).symbols.Add((BTNode)symbol))
             FreeSymbol(symbol);
       }
@@ -586,6 +590,8 @@ Declaration MkDeclarationInst(Instantiation inst)
       type = MkClassTypeSymbol(inst._class.symbol);
    };
    symbol.idCode = symbol.id = curContext.nextID++;
+   if(strstr(symbol.string, "::"))
+      curContext.hasNameSpace = true;
    if(!(curContext.templateTypesOnly ? curContext.parent : curContext).symbols.Add((BTNode)symbol))
       excludedSymbols->Add(symbol);
    decl.symbol = inst.symbol = symbol;
@@ -736,6 +742,8 @@ Declaration MkDeclaration(OldList specifiers, OldList initDeclarators)
                if(!symbol)
                {
                   symbol = Symbol { string = CopyString(id.string), type = ProcessType(specifiers, d.declarator) };
+                  if(strstr(symbol.string, "::"))
+                     curContext.hasNameSpace = true;
                   if(!(curContext.templateTypesOnly ? curContext.parent : curContext).symbols.Add((BTNode)symbol))
                      excludedSymbols->Add(symbol);
                   // TODO: Add better support to count declarators
@@ -948,6 +956,8 @@ void ProcessFunctionBody(FunctionDefinition func, Statement body)
       }
       symbol = Symbol { string = CopyString(id.string), type = ProcessType(func.specifiers, declarator) };
       symbol.idCode = symbol.id = globalContext.nextID++;
+      if(strstr(symbol.string, "::"))
+         globalContext.hasNameSpace = true;
       if(!globalContext.symbols.Add((BTNode)symbol))
          excludedSymbols->Add(symbol);
       declarator.symbol = symbol;
@@ -958,6 +968,8 @@ void ProcessFunctionBody(FunctionDefinition func, Statement body)
       excludedSymbols->Remove(declarator.symbol);
       delete symbol.string;
       symbol.string = CopyString(GetDeclId(declarator).string);
+      if(strstr(symbol.string, "::"))
+         globalContext.hasNameSpace = true;
       if(!globalContext.symbols.Add((BTNode)symbol))
          excludedSymbols->Add(symbol);
 
index 4d56a41..b95d824 100644 (file)
@@ -899,6 +899,7 @@ public:
    BinaryTree templateTypes { CompareKey = (void *)BinaryTree::CompareString };
    ClassDefinition classDef;
    bool templateTypesOnly;
+   bool hasNameSpace;
 };
 
 /*************** Compiling passes symbols ***************/
index e3efde9..6b5ea65 100644 (file)
@@ -2094,6 +2094,9 @@ void ProcessInstantiationType(Instantiation inst)
                         printf("TOCHECK: Will this ever be in a list? Yes.\n");
                         excludedSymbols->Remove(declarator.symbol);
                         globalContext.symbols.Add((BTNode)declarator.symbol);
+                        if(strstr(declarator.symbol.string), "::")
+                           globalContext.hasNameSpace = true;
+
                      }
                      */
                   
@@ -6044,28 +6047,37 @@ void CheckTemplateTypes(Expression exp)
       }
    }
 }
+// TODO: The Symbol tree should be reorganized by namespaces
+// Name Space:
+//    - Tree of all symbols within (stored without namespace)
+//    - Tree of sub-namespaces
 
 static Symbol ScanWithNameSpace(BinaryTree tree, char * nameSpace, char * name)
 {
-   Symbol symbol;
    int nsLen = strlen(nameSpace);
-   for(symbol = (Symbol)tree.first; symbol; symbol = (Symbol)((BTNode)symbol).next)
+   Symbol symbol;
+   // Start at the name space prefix
+   for(symbol = (Symbol)tree.FindPrefix(nameSpace); symbol; symbol = (Symbol)((BTNode)symbol).next)
    {
-      if(!strncmp(symbol.string, nameSpace, nsLen))
+      char * s = symbol.string;
+      if(!strncmp(s, nameSpace, nsLen))
       {
+         // This supports e.g. matching ecere::Socket to ecere::net::Socket
          int c;
          char * namePart;
-         for(c = strlen(symbol.string)-1; c >= 0; c--)
-            if(symbol.string[c] == ':')
+         for(c = strlen(s)-1; c >= 0; c--)
+            if(s[c] == ':')
                break;
 
-         namePart = symbol.string+c+1;
+         namePart = s+c+1;
          if(!strcmp(namePart, name))
          {
             // TODO: Error on ambiguity
             return symbol;
          }
       }
+      else
+         break;
    }
    return null;
 }
@@ -6089,17 +6101,31 @@ static Symbol FindWithNameSpace(BinaryTree tree, char * name)
    while(c >= 0 && name[c] == ':') c--;
    if(c >= 0)
    {
+      // Try an exact match first
+      Symbol symbol = (Symbol)tree.FindString(name);
+      if(symbol)
+         return symbol;
+
+      // Namespace specified
       memcpy(nameSpace, name, c + 1);
       nameSpace[c+1] = 0;
+
       return ScanWithNameSpace(tree, nameSpace, namePart);
    }
    else if(gotColon)
    {
+      // Looking for a global symbol, e.g. ::Sleep()
       Symbol symbol = (Symbol)tree.FindString(namePart);
       return symbol;
    }
    else
+   {
+      // Name only (no namespace specified)
+      Symbol symbol = (Symbol)tree.FindString(namePart);
+      if(symbol)
+         return symbol;
       return ScanWithNameSpace(tree, "", namePart);
+   }
    return null;
 }
 
@@ -6118,7 +6144,7 @@ static void ProcessDeclaration(Declaration decl);
 
    for(ctx = startContext; ctx /*!= topContext.parent */&& !symbol; ctx = ctx.parent)
    {
-      if(ctx == globalContext && !globalNameSpace)
+      if(ctx == globalContext && !globalNameSpace && ctx.hasNameSpace)
       {
          symbol = null;
          if(thisNameSpace)
@@ -6127,15 +6153,14 @@ static void ProcessDeclaration(Declaration decl);
             strcpy(curName, thisNameSpace);
             strcat(curName, "::");
             strcat(curName, name);
+            // Try to resolve in current namespace first
             symbol = FindWithNameSpace(isStruct ? ctx.structSymbols : ctx.symbols, curName);
          }
          if(!symbol)
             symbol = FindWithNameSpace(isStruct ? ctx.structSymbols : ctx.symbols, name);
       }
-      else if(isStruct)
-         symbol = (Symbol)ctx.structSymbols.FindString(name);
       else
-         symbol = (Symbol)ctx.symbols.FindString(name);
+         symbol = (Symbol)(isStruct ? ctx.structSymbols : ctx.symbols).FindString(name);
 
       if(symbol || ctx == endContext) break;
    }
@@ -8779,6 +8804,8 @@ void ProcessExpressionType(Expression exp)
                      Compiler_Warning("%s undefined; assuming extern returning int\n", string);
                   symbol = Symbol { string = CopyString(string), type = ProcessTypeString("int()", true) };
                   globalContext.symbols.Add((BTNode)symbol);
+                  if(strstr(symbol.string, "::"))
+                     globalContext.hasNameSpace = true;
 
                   yylloc = oldyylloc;
                }
index 42c8dc7..3d8dbaa 100644 (file)
@@ -239,6 +239,39 @@ private:
       return this;
    }
 
+   public BTNode FindPrefix(char * key)
+   {
+      BTNode subString = null;
+      int len = key ? strlen(key) : 0;
+      while(this)
+      {
+         int result;
+         if(key && this.key)
+            result = strcmp(key, (char *)this.key);
+         else if(key && !this.key)
+            result = 1;
+         else if(!key && this.key)
+            result = -1;
+         else
+            result = 0;
+
+         if(result < 0)
+         {
+            if(!strncmp(key, (char *)this.key, len))
+               subString = this;
+            this = left;
+         }
+         else if(result > 0)
+            this = right;
+         else
+         {
+            subString = this;
+            break;
+         }
+      }
+      return subString;
+   }
+
    BTNode FindAll(uint key)
    {
       BTNode result = null;
index 13bfc36..30d5ed4 100644 (file)
@@ -75,6 +75,11 @@ public struct BinaryTree
       return root ? root.FindString(key) : null;
    }
 
+   BTNode FindPrefix(char * key)
+   {
+      return root ? root.FindPrefix(key) : null;
+   }
+
    BTNode FindAll(uint key)
    {
       return root ? root.FindAll(key) : null;