as3: improved protected handling, xml support. added 'arguments' keyword
[swftools.git] / lib / as3 / expr.c
index 60c08bc..69d2fbb 100644 (file)
 
 static classinfo_t*join_types(classinfo_t*type1, classinfo_t*type2, nodetype_t*t)
 {
-    if(!type1 || !type2)
-        return TYPE_ANY;
-    if(TYPE_IS_ANY(type1) || TYPE_IS_ANY(type2))
+    if(TYPE_IS_ANY(type1))
         return TYPE_ANY;
+    
+    if(t == &node_plus) {
+        if(TYPE_IS_XMLLIST(type1))
+            return type1;
+        if(BOTH_INT(type1, type2))
+            return TYPE_INT;
+        if(IS_NUMBER_OR_INT(type1) && IS_NUMBER_OR_INT(type2))
+            return TYPE_NUMBER;
+        if(TYPE_IS_ANY(type2))
+            return TYPE_ANY;
+        return TYPE_OBJECT; // e.g. string+string = object
+    }
+
     if(type1 == type2)
         return type1;
     return TYPE_ANY;
@@ -132,7 +143,8 @@ static code_t* toreadwrite(code_t*in, code_t*middlepart, char justassign, char r
         write->opcode = OPCODE_SETPROPERTY;
         multiname_t*m = (multiname_t*)r->data[0];
         write->data[0] = multiname_clone(m);
-        if(m->type == QNAME || m->type == MULTINAME) {
+        if(m->type == QNAME || m->type == MULTINAME ||
+           m->type == QNAMEA || m->type == MULTINAMEA) {
             if(!justassign) {
                 prefix = abc_dup(prefix); // we need the object, too
             }
@@ -337,6 +349,7 @@ constant_t node_plus_eval(node_t*n)
         r.s = malloc(sizeof(string_t));
         r.s->str = s;
         r.s->len = l1+l2;
+        free(add);
     } else {
         r.type = CONSTANT_UNKNOWN;
     }
@@ -1464,7 +1477,11 @@ typedcode_t node_as_read(node_t*n)
     READ_HEADER_LEFTRIGHT;
     c = code_append(left.c, right.c);
     c = abc_astypelate(c);
-    t = TYPE_ANY;
+    if(TYPE_IS_CLASS(right.t) && right.t->data) {
+        t = (classinfo_t*)right.t->data;
+    } else {
+        t = TYPE_ANY;
+    }
     RET;
 }
 code_t* node_as_exec(node_t*n)
@@ -2053,7 +2070,7 @@ typedcode_t node_pluseq_read(node_t*n)
        c = abc_add_i(c);
     } else {
        c = abc_add(c);
-       c = converttype(c, TYPE_NUMBER, left.t);
+       c = converttype(c, join_types(left.t,right.t,&node_plus), left.t);
     }
     c = toreadwrite(left.c, c, 0, 0, 1);
     t = left.t;
@@ -2067,7 +2084,7 @@ code_t* node_pluseq_exec(node_t*n)
        c = abc_add_i(c);
     } else {
        c = abc_add(c);
-       c = converttype(c, TYPE_NUMBER, left.t);
+       c = converttype(c, join_types(left.t,right.t,&node_plus), left.t);
     }
     return toreadwrite(left.c, c, 0, 0, 0);
 }
@@ -2563,7 +2580,12 @@ typedcode_t node_const_read(node_t*n)
         case CONSTANT_NAMESPACE_PRIVATE:
             c = abc_pushnamespace(0, v->ns);
         break;
-        default: syntaxerror("invalid constant");
+        case CONSTANT_UNKNOWN:
+            syntaxerror("internal error: invalid constant");
+        default: 
+            *(int*)0=0;
+            syntaxerror("invalid constant (%d)", v->type);
+
     }
     RET;
 }
@@ -2597,9 +2619,9 @@ typedcode_t node_code_write(node_t*n)
 }
 typedcode_t node_code_read(node_t*n)
 {
-    /* TODO: this dup might be unnecessary- n->code.c is only read out once */
     typedcode_t t;
-    t.c = code_dup(n->code.c);
+    t.c = n->code.c;
+    n->code.c=0;
     t.t = n->code.t;
     return t;
 }
@@ -2744,13 +2766,13 @@ node_t* mknode3(nodetype_t*t, node_t*one, node_t*two, node_t*three)
 void node_free(node_t*n)
 {
     int t;
-    if(n->type == &node_const) {
-        constant_free(n->value);n->value = 0;
-    }
-    else if(n->type == &node_code) {
-        code_free(n->code.c);n->code.c = 0;
-    }
-    else for(t=0;t<n->num_children;t++) {
+    if(n->type == &node_code) {
+        if(n->code.c) {
+            code_free(n->code.c);n->code.c = 0;
+        }
+    } else if(n->type == &node_const) {
+        /* keep, this is not our reference */
+    } else for(t=0;t<n->num_children;t++) {
         node_free(n->child[t]);n->child[t] = 0;
     }
     free(n);
@@ -2812,7 +2834,7 @@ void node_dump2(node_t*n, const char*p1, const char*p2, FILE*fi)
         fprintf(fi, "%s%s (%s)\n", p1, n->type->name, s);
         free(s);
     } else if(n->type == &node_code) {
-        fprintf(fi, "%s%s\n", p1, n->type->name);
+        fprintf(fi, "%s%s (%s)\n", p1, n->type->name, n->code.t?n->code.t->name:"*");
         code_dump2(n->code.c, 0, 0, (char*)p2, fi);
     } else {
         fprintf(fi, "%s%s\n", p1, n->type->name);
@@ -2821,8 +2843,8 @@ void node_dump2(node_t*n, const char*p1, const char*p2, FILE*fi)
 
 void node_dump(node_t*n)
 {
-    printf("---------------------------VVVV\n");
+    printf("------------VVVV---------------\n");
     node_dump2(n,"","",stdout);
-    printf("---------------------------^^^^\n");
+    printf("-------------------------------\n");
 }