+ if(!callcode(current, 0, 0, 0)) {
+ free(current);
+ return 0;
+ }
+ exception_list_t*e = exceptions;
+ while(e) {
+ if(e->exception->target)
+ callcode(current, e->exception->target->pos, 1, 0);
+ e = e->next;
+ }
+
+ return current;
+}
+
+int code_dump(code_t*c, exception_list_t*exceptions, abc_file_t*file, char*prefix, FILE*fo)
+{
+ exception_list_t*e = exceptions;
+ c = code_find_start(c);
+ currentstats_t*stats = code_get_stats(c, exceptions);
+
+ pool_t*pool = pool_new();
+
+ int pos = 0;
+ while(c) {
+ U8 opcode = c->opcode;
+ char found = 0;
+ opcode_t*op = opcode_get(opcode);
+
+ e = exceptions;
+ while(e) {
+ if(c==e->exception->from)
+ fprintf(fo, "%s TRY {\n", prefix);
+ if(c==e->exception->target) {
+ char*s1 = multiname_to_string(e->exception->exc_type);
+ char*s2 = multiname_to_string(e->exception->var_name);
+ fprintf(fo, "%s CATCH(%s %s)\n", prefix, s1, s2);
+ free(s1);
+ free(s2);
+ }
+ e = e->next;
+ }
+
+ if(!op) {
+ fprintf(stderr, "Can't parse opcode %02x.\n", opcode);
+ return 0;
+ } else {
+ char*p = op->params;
+ char first = 1;
+ int i=0;
+
+ fprintf(fo, "%s%5d) %c %d:%d %s ", prefix, c->pos, stats->stack[c->pos].seen?'x':'|',
+ stats->stack[c->pos].stackpos,
+ stats->stack[c->pos].scopepos,
+ op->name);
+
+ while(*p) {
+ void*data = c->data[i];
+ if(i>0)
+ printf(", ");
+
+ if(*p == 'n') {
+ int n = (ptroff_t)data;
+ fprintf(fo, "%d params", n);
+ } else if(*p == '2') {
+ multiname_t*n = (multiname_t*)data;
+ char* m = multiname_to_string(n);
+ fprintf(fo, "%s", m);
+ free(m);
+ } else if(*p == 'm') {
+ abc_method_t*m = (abc_method_t*)data;
+ fprintf(fo, "[method %s]", m->name);
+ } else if(*p == 'c') {
+ abc_class_t*cls = (abc_class_t*)data;
+ char*classname = multiname_to_string(cls->classname);
+ fprintf(fo, "[classinfo %s]", classname);
+ free(classname);
+ } else if(*p == 'i') {
+ abc_method_body_t*b = (abc_method_body_t*)data;
+ fprintf(fo, "[methodbody]");
+ } else if(*p == 'u') {
+ int n = (ptroff_t)data;
+ fprintf(fo, "%d", n);
+ } else if(*p == 'r') {
+ int n = (ptroff_t)data;
+ fprintf(fo, "r%d", n);
+ } else if(*p == 'b') {
+ int b = (ptroff_t)data;
+ fprintf(fo, "%02x", b);
+ } else if(*p == 'j') {
+ if(c->branch)
+ fprintf(fo, "->%d", c->branch->pos);
+ else
+ fprintf(fo, "%08x", c->branch);
+ } else if(*p == 's') {
+ fprintf(fo, "\"%s\"", data);
+ } else if(*p == 'D') {
+ fprintf(fo, "[register %02x=%s]", (ptroff_t)c->data[1], (char*)c->data[0]);
+ } else if(*p == 'S') {
+ lookupswitch_t*l = c->data[0];
+ fprintf(fo, "[");
+ if(l->def)
+ fprintf(fo, "default->%d", l->def->pos);
+ else
+ fprintf(fo, "default->00000000", l->def->pos);
+ code_list_t*t = l->targets;
+ while(t) {
+ if(t->code)
+ fprintf(fo, ",->%d", t->code->pos);
+ else
+ fprintf(fo, ",->00000000");
+ t = t->next;
+ }
+ fprintf(fo, "]");
+ } else {
+ fprintf(stderr, "Can't parse opcode param type \"%c\"\n", *p);
+ return 0;
+ }
+ p++;
+ i++;
+ first = 0;
+ }
+ fprintf(fo, "\n");
+ }
+
+ 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);
+ else
+ fprintf(fo, "%s } // END TRY (HANDLER: 00000000)\n", prefix);
+ }
+ e = e->next;
+ }
+
+ pos++;
+ c = c->next;
+ }
+ return 1;
+}