class_signature now contains flags
[swftools.git] / lib / as3 / code.c
index f3b9b98..49f794e 100644 (file)
@@ -152,9 +152,7 @@ opcode_t opcodes[]={
 {0x57, "newactivation", "",     0, 1, 0, OP_NEED_ACTIVATION},
 {0x56, "newarray", "n",         0, 1, 0, OP_STACK_ARGS},
 {0x5a, "newcatch", "u",         0, 1, 0, 0}, //u = index into exception_info
-#define OP_NEWCLASS 0x58
 {0x58, "newclass", "c",        -1, 1, 0, 0}, //c = index into class_info
-#define OP_NEWFUNCTION 0x40
 {0x40, "newfunction", "m",      0, 1, 0, 0}, //i = index into method_info
 {0x55, "newobject", "n",        0, 1, 0, OP_STACK_ARGS2},
 {0x1e, "nextname", "",         -2, 1, 0, 0},
@@ -198,9 +196,8 @@ opcode_t opcodes[]={
 {0xa7, "urshift", "",          -2, 1, 0, 0},
 
 /* opcodes not documented, but seen in the wild */
-//0x53: seen in builtin.abc- followed by 0x01 (might be the number of stack params)
-{0x53, "xxx1", "",             -1, 0, 0, 0},
-{0x01, "xxx2", "",              0, 0, 0, 0},
+//0x53: seen in builtin.abc
+{0x53, "applytype", "n",       -1, 1, 0, OP_STACK_ARGS},
 
 /* dummy instruction. Warning: this one is not actually supported by flash */
 {0xff, "__break__", "",             0, 0, 0, OP_RETURN},
@@ -684,12 +681,12 @@ static char callcode(currentstats_t*stats, int pos, int stack, int scope)
         if(op->flags & OP_NEED_ACTIVATION)
             stats->flags |= FLAGS_ACTIVATION;
 
-        if(c->opcode == OP_NEWCLASS) {
+        if(c->opcode == OPCODE_NEWCLASS) {
             abc_class_t*cls = (abc_class_t*)(c->data[0]);
             if(scope > cls->init_scope_depth)
                 cls->init_scope_depth = scope;
         }
-        if(c->opcode == OP_NEWFUNCTION) {
+        if(c->opcode == OPCODE_NEWFUNCTION) {
             abc_method_t*m = (abc_method_t*)(c->data[0]);
             if(m->body && scope > m->body->init_scope_depth)
                 m->body->init_scope_depth = scope;
@@ -826,8 +823,8 @@ static currentstats_t* code_get_stats(code_t*code, abc_exception_list_t*exceptio
     }
     abc_exception_list_t*e = exceptions;
     while(e) {
-        if(e->exception->target)
-            callcode(current, e->exception->target->pos, 1, 0);
+        if(e->abc_exception->target)
+            callcode(current, e->abc_exception->target->pos, 1, 0);
         e = e->next;
     }
 
@@ -856,11 +853,11 @@ int code_dump(code_t*c, abc_exception_list_t*exceptions, abc_file_t*file, char*p
 
         e = exceptions;
         while(e) {
-            if(c==e->exception->from)
+            if(c==e->abc_exception->from)
                 fprintf(fo, "%s   TRY {\n", prefix);
-            if(c==e->exception->target) {
-                char*s1 = multiname_tostring(e->exception->exc_type);
-                char*s2 = multiname_tostring(e->exception->var_name);
+            if(c==e->abc_exception->target) {
+                char*s1 = multiname_tostring(e->abc_exception->exc_type);
+                char*s2 = multiname_tostring(e->abc_exception->var_name);
                 fprintf(fo, "%s   CATCH(%s %s)\n", prefix, s1, s2);
                 free(s1);
                 free(s2);
@@ -961,9 +958,9 @@ int code_dump(code_t*c, abc_exception_list_t*exceptions, abc_file_t*file, char*p
         
         e = exceptions;
         while(e) {
-            if(c==e->exception->to) {
-                if(e->exception->target)
-                    fprintf(fo, "%s   } // END TRY (HANDLER: %d)\n", prefix, e->exception->target->pos);
+            if(c==e->abc_exception->to) {
+                if(e->abc_exception->target)
+                    fprintf(fo, "%s   } // END TRY (HANDLER: %d)\n", prefix, e->abc_exception->target->pos);
                 else
                     fprintf(fo, "%s   } // END TRY (HANDLER: 00000000)\n", prefix);
             }
@@ -1048,3 +1045,63 @@ code_t* code_append(code_t*code, code_t*toappend)
     return code_end(toappend);
 }
 
+lookupswitch_t*lookupswitch_dup(lookupswitch_t*l)
+{
+    lookupswitch_t*n = malloc(sizeof(lookupswitch_t));
+    fprintf(stderr, "lookupswitch dupping not supported yet\n");
+    n->targets = list_clone(l->targets);
+    return 0;
+}
+
+code_t*code_dup(code_t*c)
+{
+    /* misses branch relocation */
+    fprintf(stderr, "dupping not supported yet\n");
+    return 0;
+    if(!c) return 0;
+
+    while(c->prev) c = c->prev;
+
+    code_t*last = 0;
+    while(c) {
+        NEW(code_t, n);
+        memcpy(n, c, sizeof(code_t));
+
+        opcode_t*op = opcode_get(c->opcode);
+        char*p = op?op->params:"";
+        int pos=0;
+        while(*p) {
+            if(*p == '2') { //multiname
+                c->data[pos] = multiname_clone(c->data[pos]);
+            } else if(*p == 's' || *p == 'D') {
+                c->data[pos] = strdup(c->data[pos]);
+            } else if(*p == 'f') {
+                double old = *(double*)c->data[pos];
+                c->data[pos] = malloc(sizeof(double));
+                *(double*)c->data[pos] = old;
+            } else if(strchr("S", *p)) {
+                c->data[pos] = lookupswitch_dup(c->data[pos]);
+            }
+            p++;pos++;
+        }
+
+        n->prev = last;
+        if(last) {
+            last->next = n;
+        }
+        last = n;
+        c = c->next;
+    }
+    return last;
+}
+
+code_t*code_cutlast(code_t*c)
+{
+    assert(!c->next);
+    code_t*prev = c->prev;
+    c->prev = 0;
+    prev->next=0;
+    code_free(c);
+    return prev;
+}
+