/* context.c * (c) 2002 Martin 'PerM' Pergel * This file is a part of the Links program, released under GPL. */ #include "cfg.h" #ifdef JS #include "struct.h" #include "tree.h" #include "typy.h" #include "ipret.h" #include "builtin.h" #define idebug(a) printf(a) #undef idebug #define idebug(a) extern long MIN1KEY; #include "ns.h" extern int js_durchfall; /* typedef struct _vrchol { long opcode; int nargs; * void*arg[6]; * struct _vrchol * otec; * int prolezany; } vrchol; * * typedef struct _ns{ long identifier; vrchol*kdeje; struct _ns*next;}ns; * typedef struct javascript_context * { intercode* start,*now; * int lock; ns*namespace[HASHNUM]; }js_context; */ /* prototypes */ void vymaz(js_id_name*namespace[]); void total_clearvar(lns *, js_context *); js_context* js_create_context(void*p,long id)/*nevim co budu delat s tim p*/ { int i=0; lns** pomlns; static long links__browser_pro_opravdove_muze_a_pochlapenou_kolegyni_Dolezalovou=0; js_context*context=js_mem_alloc(sizeof(js_context)); if(!context) return NULL; init_list(context->namespaces); context->running=0; /* context->start=context->now=0;*/ context->lock=0;/*nebezime*/ while(inamespace)[i++]=0;/*Semhle se pridelaji jmena, ktera je potreba umet z fabriky (OnClick apod.)*/ context->js_tree=0; /* Strom je zatim prazdny */ context->parbuf=0; context->argbuf=0; context->current=0; context->lineno=0; context->bordel=0; context->mrtve_promenne=0; context->depth=0; context->depth1=0; context->first_ns=0; context->last_ns=&context->first_ns; context->fotrisko=context->lnamespace=js_mem_alloc(sizeof(plns)); add_to_list(context->namespaces, &context->lnamespace->xl); context->lnamespace->next=0; if(js_global_resolve) context->lnamespace->mid=js_upcall_get_window_id(p); else context->lnamespace->mid=0; context->lnamespace->handler=js_upcall_get_document_id(p); context->code=0; /* Sanity nula */ context->codelen=0; context->utraticka=0; #ifdef PRO_DEBILY context->zlomeny_ramecek_jako_u_netchcipu=0; #endif context->cookies=NULL; context->zaplatim=0;/* Co bych platil! Jeste jsem nebezel! */ pomlns=context->lnamespace->ns=js_mem_alloc(sizeof(lns*)*HASHNUM); i=0; while(iptr = p; /* Mikulas following section - almost copied */ for(i=0;it[i++]=-1); context->upcall_timer = -1; context->jsem_dead=0; context->js_id=links__browser_pro_opravdove_muze_a_pochlapenou_kolegyni_Dolezalovou++; context->id = id; /* End of Mikulas compatibility section */ add_builtin(context); return context; } void vymaz(js_id_name*namespace[]) /* There's a man going round taking names. */ { int i=0; js_id_name*a,*b; while(inext; js_mem_free(a->jmeno); js_mem_free(a); a=b; } i++; } } void zrus_strom(vrchol*pom_vrchol) /* deletes intercode-tree */ { vrchol*p; while(pom_vrchol){ p=pom_vrchol->prev; if(pom_vrchol->opcode==TNUMLIT)js_mem_free(pom_vrchol->arg[0]); if((pom_vrchol->opcode==TSTRINGLIT)||(pom_vrchol->opcode==TREGEXPLIT))js_mem_free(pom_vrchol->arg[0]); if(pom_vrchol->opcode==TFOR3)if(pom_vrchol->arg[3])js_mem_free(pom_vrchol->arg[3]); js_mem_free(pom_vrchol); pom_vrchol=p; }/*deallokujeme strom*/ } void del_ns(plns*,js_context*); void total_clearvar(lns*pna,js_context*context) { lns*zrusit; plns*fotri; switch(pna->type) { case UNDEFINED: case NULLOVY: case BOOLEAN: case INTEGER: case FUNKCE: case FUNKINT: break; case INTVAR: kill_var(pna); break; case FLOAT: case STRING: case REGEXP: js_mem_free((void*)pna->value); break; case ADDRSPACEP: case ARRAY: /* fotri=((plns*)pna->value)->next;*/ fotri=context->fotrisko; while(fotri && fotri!=(plns*)pna->value) fotri=fotri->next; if(!fotri /*&& ((plns*)pna->value)->next*/) { del_ns((plns*)pna->value,context); } else { zrusit=lookup(MIN1KEY,(plns*)pna->value,context); if(zrusit->type!=PARLIST) internal("Parent-list corrupted!\n"); delete_from_parlist(pna,zrusit); /* Pokus na nas ukazuje nej. parent, konec. */ } break; default: internal("Aiee! Unknown variable type!\n"); break; } /* js_mem_free(pna);*/ } void clearvars(parlist*list); void del_ns(plns*pns,js_context*context) /* deletes table of keys and values of vars */ /* Jezkovy voci !!! Tohle uz dela deletenamespace. Ten PerM je ale cune --- mikulas */ { int i=0; lns**ns; /* Pozor mozna prasarna! */ lns*a,*b; ns=pns->ns; if(!ns) my_internal("Del_ns is trying to free NULL addrspace!\n",context); while(itype != PARLIST) a=a->next; if(a) { clearvars((parlist*)a->value); a->value=0; a->type=UNDEFINED; } } i=0; while(inext; if(a->type==PARLIST) my_internal("Too many parlists!\n",context) /* ;*/ else total_clearvar(a,context); js_mem_free(a); a=b; } i++; } del_from_list(&pns->xl); js_mem_free(ns); js_mem_free(pns); } /* Tohle by melo kontext trochu procistit, aby utocnik nemohl vykillit vsechny kontexty tim, ze pretece a ostatni jak budou alokovat, tak do toho ridkeho trusu sahnou taky. */ void js_cistka_kontextu(js_context*context) { borlist* na_bordel=context->bordel,*pom; abuf*bufer; struct jsnslist* odlozene_deti; varlist*svinec; idebug("Cistka kontextu!\n"); while(na_bordel){ js_mem_free(na_bordel->binec); pom=na_bordel->next; js_mem_free(na_bordel); na_bordel=pom; } context->bordel=0; while(pullp(context))idebug("Killing parent in buffer!\n"); while((bufer=pulla(context))) { delarg(bufer,context); idebug("Killing buffer entry!\n"); } /*Neco takoveho tu bude potreba, ale lepe a radostneji :-) */ while(context->first_ns) { odlozene_deti=context->first_ns->next; deletenamespace(context->first_ns->pns,context,0); js_mem_free(context->first_ns); context->first_ns=odlozene_deti; } zrus_strom(context->js_tree); context->js_tree=0; context->current=0; /* Carovani se stromem alla Rumcajs */ while((svinec=context->mrtve_promenne)) { context->mrtve_promenne=context->mrtve_promenne->next; clearvar(svinec->lekla_ryba,context); js_mem_free(svinec->lekla_ryba); js_mem_free(svinec); idebug("Killim leklou promennou!\n"); } } void js_destroy_context(js_context* context) { plns *ns1,*ns2; abuf*bufer; int timerno; struct jsnslist* odlozene_deti; borlist*pom,*na_bordel=context->bordel; varlist*svinec; lns*promenna; #if 0 /* PerM je cune. Hrabe kam nema a pak to quli tomu pada */ struct __warning_list_t *wokno; /* js_durchfall=0; */ foreach(wokno,warning_list)/* Smahneme Brainovi warningy B-) */ { struct __warning_list_t *w=wokno; wokno=wokno->prev; del_from_list(w); js_mem_free(w); } #endif while(na_bordel){ js_mem_free(na_bordel->binec); pom=na_bordel->next; js_mem_free(na_bordel); na_bordel=pom; } while(pullp(context))idebug("Killing parent in buffer!\n"); while((bufer=pulla(context))) { delarg(bufer,context); idebug("Killing buffer entry!\n"); } /*Neco takoveho tu bude potreba, ale lepe a radostneji :-) */ promenna=lookup(MIN1KEY,context->lnamespace,context); if(promenna->type!=PARLIST) my_internal("Parentlist corrupted!",context); if(!promenna->value) deletenamespace(context->lnamespace,context,0); while(context->first_ns) { odlozene_deti=context->first_ns->next; deletenamespace(context->first_ns->pns,context,0); js_mem_free(context->first_ns); context->first_ns=odlozene_deti; } ns1=context->fotrisko; while(ns1){ ns2=ns1->next; del_ns(ns1,context); context->fotrisko=ns1=ns2; } /* To jsou deallokace promennych */ zrus_strom(context->js_tree); while((svinec=context->mrtve_promenne)) { context->mrtve_promenne=context->mrtve_promenne->next; clearvar(svinec->lekla_ryba,context); js_mem_free(svinec->lekla_ryba); js_mem_free(svinec); idebug("Killim leklou promennou!\n"); } if(context->code)js_mem_free(context->code); else { idebug("Strange things happen!\n"); } vymaz(context->namespace); if (!list_empty(context->namespaces)) { struct xlist_head *xl; foreach(xl, context->namespaces) { plns *pl = (plns *)((char *)xl - (int)&((plns *)NULL)->xl); deletenamespace(pl, context, 1); } while (!list_empty(context->namespaces)) { plns *pl = (plns *)((char *)context->namespaces.next - (int)&((plns *)NULL)->xl); deletenamespace(pl, context, 0); } } for(timerno=0;timernot[timerno]!=-1) { kill_timer(context->t[timerno]); context->t[timerno]=-1; idebug("Killim timer!\n"); js_mem_free(context->bordely[timerno]); } if(context->upcall_timer!=-1) js_spec_vykill_timer(context,1); if(context->depth) { idebug("Za jizdy z vlaku NE-SE-SKA-KO-VAT!\n"); } if(context->depth1) { idebug("Za jizdy z vlaku NESESKAKOVAT!\n"); } if (context->cookies)js_mem_free(context->cookies); js_mem_free(context); /* A je to*/ } #endif