as3: fixed some reconcile problems
[swftools.git] / lib / as3 / registry.c
index cbd931f..5f45c6a 100644 (file)
@@ -48,6 +48,12 @@ static unsigned int slotinfo_hash(slotinfo_t*c)
     hash = crc32_add_string(hash, c->name);
     return hash;
 }
+static unsigned int memberinfo_hash(slotinfo_t*c)
+{
+    unsigned int hash = 0;
+    hash = crc32_add_string(hash, c->name);
+    return hash;
+}
 
 static void* dummy_clone(void*other) {return other;}
 static void dummy_destroy(slotinfo_t*c) {}
@@ -58,6 +64,12 @@ type_t slotinfo_type = {
     dup: (dup_func)dummy_clone, // all signatures are static
     free: (free_func)dummy_destroy,
 };
+type_t memberinfo_type = {
+    hash: (hash_func)memberinfo_hash,
+    equals: (equals_func)slotinfo_equals,
+    dup: (dup_func)dummy_clone, // all signatures are static
+    free: (free_func)dummy_destroy,
+};
 
 // ----------------------- resolving ----------------------------------
 slotinfo_t* registry_resolve(slotinfo_t*_s)
@@ -85,7 +97,7 @@ static void schedule_for_resolve(slotinfo_t*s)
 }
 static void resolve_on_slot(slotinfo_t*_member)
 {
-    if(_member->kind == INFOTYPE_SLOT) {
+    if(_member->kind == INFOTYPE_VAR) {
         varinfo_t*member = (varinfo_t*)_member;
         member->type = (classinfo_t*)registry_resolve((slotinfo_t*)member->type);
     } else if(_member->kind == INFOTYPE_METHOD) {
@@ -117,7 +129,7 @@ void registry_resolve_all()
         slotinfo_t*_s = unresolved->slotinfo;
         if(_s->kind == INFOTYPE_CLASS) {
             resolve_on_class(_s);
-        } else if(_s->kind == INFOTYPE_METHOD || _s->kind == INFOTYPE_SLOT) {
+        } else if(_s->kind == INFOTYPE_METHOD || _s->kind == INFOTYPE_VAR) {
             resolve_on_slot(_s);
         } else {
             fprintf(stderr, "Internal Error: object %s.%s has bad type\n", _s->package, _s->name);
@@ -139,7 +151,7 @@ classinfo_t* classinfo_register(int access, const char*package, const char*name,
     c->package = package;
     c->name = name;
     dict_put(registry_classes, c, c);
-    dict_init2(&c->members, &slotinfo_type, AVERAGE_NUMBER_OF_MEMBERS);
+    dict_init2(&c->members, &memberinfo_type, AVERAGE_NUMBER_OF_MEMBERS);
 
     schedule_for_resolve((slotinfo_t*)c);
     return c;
@@ -158,7 +170,7 @@ methodinfo_t* methodinfo_register_onclass(classinfo_t*cls, U8 access, const char
 varinfo_t* varinfo_register_onclass(classinfo_t*cls, U8 access, const char*ns, const char*name)
 {
     NEW(varinfo_t,m);
-    m->kind = INFOTYPE_SLOT;
+    m->kind = INFOTYPE_VAR;
     m->access = access;
     m->name = name;
     m->package = ns;
@@ -183,7 +195,7 @@ methodinfo_t* methodinfo_register_global(U8 access, const char*package, const ch
 varinfo_t* varinfo_register_global(U8 access, const char*package, const char*name)
 {
     NEW(varinfo_t, m);
-    m->kind = INFOTYPE_SLOT;
+    m->kind = INFOTYPE_VAR;
     m->flags = FLAG_STATIC;
     m->access = access;
     m->package = package;
@@ -252,6 +264,9 @@ memberinfo_t* registry_findmember(classinfo_t*cls, const char*ns, const char*nam
         s = s->superclass;
 
     while(s) {
+        if(s->kind == INFOTYPE_UNRESOLVED)
+            break;
+
         m = (slotinfo_t*)dict_lookup(&s->members, &tmp);
         if(m) {
             return (memberinfo_t*)m;
@@ -278,12 +293,20 @@ memberinfo_t* registry_findmember(classinfo_t*cls, const char*ns, const char*nam
 
 memberinfo_t* registry_findmember_nsset(classinfo_t*cls, namespace_list_t*ns, const char*name, char superclasses)
 {
+    memberinfo_t*m = 0;
     while(ns) {
-        memberinfo_t*m = registry_findmember(cls, ns->namespace->name, name, superclasses);
+        m = registry_findmember(cls, ns->namespace->name, name, superclasses);
         if(m) return m;
         ns = ns->next;
     }
-    return registry_findmember(cls, "", name, superclasses);
+    m = registry_findmember(cls, "", name, superclasses);
+    if(m) return m;
+    /* TODO: it maybe would be faster to just store the builtin namespace as "" in
+             builtins.c (update: some members (e.g. XML.length) are present both for
+            "" and "http:...builtin") */
+    m = registry_findmember(cls, "http://adobe.com/AS3/2006/builtin", name, superclasses);
+    if(m) return m;
+    return 0;
 }
 
 
@@ -322,17 +345,19 @@ classinfo_t* slotinfo_asclass(slotinfo_t*f) {
     classinfo_t*c = rfx_calloc(sizeof(classinfo_t)+sizeof(classinfo_t*));
     c->access = ACCESS_PUBLIC;
     c->package = "";
-    if(f->kind == INFOTYPE_METHOD)
+    if(f->kind == INFOTYPE_METHOD) {
         c->name = "Function";
-    else if(f->kind == INFOTYPE_CLASS)
+        c->superclass = registry_getobjectclass();
+    } else if(f->kind == INFOTYPE_CLASS) {
         c->name = "Class";
-    else if(f->kind == INFOTYPE_SLOT)
+        c->superclass = registry_getobjectclass();
+    } else if(f->kind == INFOTYPE_VAR) {
         c->name = "Object";
-    else {
+    } else {
         c->name = "undefined";
     }
     
-    dict_init2(&c->members, &slotinfo_type, 1);
+    dict_init2(&c->members, &memberinfo_type, 1);
     c->data = f;
     dict_put(functionobjects, f, c);
     return c;
@@ -343,17 +368,23 @@ classinfo_t* slotinfo_gettype(slotinfo_t*f)
     if(f) {
        if(f->kind == INFOTYPE_METHOD) {
            return slotinfo_asclass(f);
-       } else if(f->kind == INFOTYPE_SLOT) {
+       } else if(f->kind == INFOTYPE_VAR) {
            varinfo_t*v = (varinfo_t*)f;
            return v->type;
        } else 
            return 0;
     } else {
-       return registry_getanytype();
+       return TYPE_ANY;
     }
 }
+
+// ----------------------- package handling ---------------------------
+char registry_ispackage(char*package)
+{
+    /* crude approximation of "the real thing", but sufficient for now */
+    return !strncmp(package, "flash", 5);
+}
 // ----------------------- builtin types ------------------------------
-classinfo_t* registry_getanytype() {return 0;}
 
 char registry_isfunctionclass(classinfo_t*c) {
     return (c && c->package && c->name && 
@@ -404,6 +435,26 @@ classinfo_t* registry_getregexpclass() {
     if(!c) c = (classinfo_t*)registry_safefind("", "RegExp");
     return c;
 }
+classinfo_t* registry_getdateclass() {
+    static classinfo_t*c = 0;
+    if(!c) c = (classinfo_t*)registry_safefind("", "Date");
+    return c;
+}
+classinfo_t* registry_getxmlclass() {
+    static classinfo_t*c = 0;
+    if(!c) c = (classinfo_t*)registry_safefind("", "XML");
+    return c;
+}
+classinfo_t* registry_getxmllistclass() {
+    static classinfo_t*c = 0;
+    if(!c) c = (classinfo_t*)registry_safefind("", "XMLList");
+    return c;
+}
+classinfo_t* registry_getnamespaceclass() {
+    static classinfo_t*c = 0;
+    if(!c) c = (classinfo_t*)registry_safefind("", "Namespace");
+    return c;
+}
 classinfo_t* registry_getMovieClip() {
     static classinfo_t*c = 0;
     if(!c) c = (classinfo_t*)registry_safefind("flash.display", "MovieClip");
@@ -417,6 +468,12 @@ classinfo_t nullclass = {
 classinfo_t* registry_getnullclass() {
     return &nullclass;
 }
+classinfo_t voidclass = {
+    INFOTYPE_CLASS,0,0,ACCESS_PACKAGE, "", "void", 0, 0, 0
+};
+classinfo_t* registry_getvoidclass() {
+    return &voidclass;
+}
 
 namespace_t access2namespace(U8 access, char*package)
 {
@@ -429,8 +486,34 @@ namespace_t access2namespace(U8 access, char*package)
 char* infotypename(slotinfo_t*s)
 {
     if(s->kind == INFOTYPE_CLASS) return "class";
-    else if(s->kind == INFOTYPE_SLOT) return "member";
-    else if(s->kind == INFOTYPE_METHOD) return "method";
+    else if(s->kind == INFOTYPE_VAR) return "var";
+    else if(s->kind == INFOTYPE_METHOD) return "function";
     else return "object";
 }
 
+void slotinfo_dump(slotinfo_t*s)
+{
+    if(s->package[0]) {
+        printf("%s %s.%s", infotypename(s), s->package, s->name);
+    } else {
+        printf("%s %s", infotypename(s), s->name);
+    }
+    if(s->kind == INFOTYPE_CLASS) {
+        classinfo_t*c = (classinfo_t*)s;
+    }
+    else if(s->kind == INFOTYPE_VAR) {
+        varinfo_t*v = (varinfo_t*)s;
+        printf(":%s", v->type?v->type->name:"*");
+        if(v->value)
+            printf("=%s", constant_tostring(v->value));
+        if(v->slot)
+            printf(" (slot:%d)", v->slot);
+    }
+    else if(s->kind == INFOTYPE_METHOD) {
+        methodinfo_t*m = (methodinfo_t*)s;
+    }
+    else {
+    }
+    printf("\n");
+}
+