Пример #1
0
Файл: parse.c Проект: xtao/c
static void
fbody(void)
{
	Node   *gotofixup;
	int     i;
	char   *l;
	NameTy *nt;
	Sym    *sym;

	pushscope();
	labels = map();
	gotos = vec();
	for(i = 0; i < curfunc->type->Func.params->len; i++) {
		nt = vecget(curfunc->type->Func.params, i);
		if(nt->name) {
			sym = definesym(&curfunc->pos, SCAUTO, nt->name, nt->type, 0);
			vecappend(curfunc->Func.params, sym);
		}
	}
	curfunc->Func.body = block();
	popscope();
	for(i = 0 ; i < gotos->len ; i++) {
		gotofixup = vecget(gotos, i);
		l = mapget(labels, gotofixup->Goto.name);
		if(!l)
			errorposf(&gotofixup->pos, "goto target does not exist");
		gotofixup->Goto.l = l;
	}
}
Пример #2
0
Файл: parse.c Проект: xtao/c
void 
parse()
{
	int i;
	Sym *sym;

	switchdepth = 0;
	brkdepth = 0;
	contdepth = 0;
	nscopes = 0;
	tentativesyms = vec();
	pushscope();
	next();
	next();
	while(tok->k != TOKEOF)
		decl();
	for(i = 0; i < tentativesyms->len; i++) {
		sym = vecget(tentativesyms, i);
		emitsym(sym);
	}
}
Пример #3
0
void
proggen(Node *t, Node *n)
{
	int or;
	Node *of;
	Errjmp s;
	Store *p;
	long len, loc;
	long nauto, oao;
	int osp, odb;
	extern int (**prog)(Proc*);
	extern int storeprog;
	odb=didbecome;
	oao=autooffset;
	or=returnloc;
	of=formals;
	osp=storeprog;
	autooffset=0;
	returnloc=0;
	formals=t->l;
	errsave(s);
	if(errmark()){
		didbecome=odb;
		returnloc=or;
		formals=of;
		autooffset=oao;
		storeprog=osp;
		errrest(s);
		errjmp();
	}
	loc=here();
	emitconst(0);	/* space for locals pointer */
	pushscope();
	dclformals(t->l);
	autooffset=0;
	emit(Ipushfp);
	nauto=here();
	storeprog=here();
	emitconst(0L);
	gen(n, 0);
	trlrgen();
	patch((int)nauto, autooffset);
	popscope();
	errrest(s);
	if(!didbecome && n && t->r->o.t!=TUnit)
		lerror(n, "prog has no become");
	didbecome=odb;
	autooffset=oao;
	returnloc=or;
	formals=of;
	storeprog=osp;
	len=here()-loc+1;
	p=emalloc(SHSZ+len*WS);
	memcpy(p->data, prog+loc, len*WS);
	p->ref=1;
	p->len=len;
	p->type=Sprog;
	setprog(loc);
	emit(Ipushdata);
	emitconst((long)p);
	emitstore(p);
}
Пример #4
0
void
gen(Node *n, int retain)
{
	int i;

	if(n==0)
		return;
	switch(n->t){
	case NArrayref:
		arygen(n->l, n->r, 0, 0L);
		if(!retain)
			popgen(n->l->o.s->val->type->r);
		return;
	case NBecome:
		didbecome=1;
		if(n->l->t==NCall && !bflag){
			callgen(n->l, Ibecome);
			return;
		}
		gen(n->l, 1);
		n=n->r;
		if(n->o.t==TID)
			n=typeoftid(n);
		switch(n->o.t){
		case TInt:
		case TChar:
			emit(Istoreauto);
			emitconst(-WS*(4+length(formals)));
			break;
		case TArray:
		case TChan:
		case TProg:
		case TStruct:
			emit(Istoreptrauto);
			emitconst(-WS*(4+length(formals)));
			break;
		case TUnit:
			break;
		default:
			panic("can't compile %t become", n);
		}
		scopedecrefgen();
		trlrgen();
		return;
	case NBegin:
		callgen(n->l, Ibegin);
		return;
	case NBreak:
		if(breakloc==-1)
			lerror(n, "break not in loop");
		if(breakloc)	/* chain previous break to here */
			patch(breakloc, (long)(here()-breakloc-1)*WS);
		emit(Ijmp);
		breakloc=here();
		emitconst(0L);
		return;
	case NCall:
		callgen(n, Icall);
		if(!retain)
			popgen(etypeoft(n->l)->r);
		return;
	case NComplete:
		gen(n->l, retain);
		return;
	case NContinue:
		if(continueloc==-1)
			lerror(n, "continue not in loop");
		if(continueloc)	/* chain previous continue to here */
			patch(continueloc, (long)(here()-continueloc-1)*WS);
		emit(Ijmp);
		continueloc=here();
		emitconst(0L);
		return;
	case NDecl:
	case NDeclsc:
		declare(n, 0, 0, 1);
		return;
	case NExpr:
		switch(n->o.i){
		case GE:
			i=Ige;
		Binop:
			gen(n->l, 1);
			gen(n->r, 1);
			if(eqtype(etypeof(n->l), &arychartype)){
				emit(Istrcmp);
				constgen(0L);
			}
			emit(i);
		Popit:
			if(!retain)
				emit(Ipop);
			return;
		case LE:
			i=Ile;
			goto Binop;
		case NE:
			i=Ine;
			goto Binop;
		case EQ:
			i=Ieq;
			goto Binop;
		case '>':
			i=Igt;
			goto Binop;
		case '<':
			i=Ilt;
			goto Binop;
		case '+':
			i=Iadd;
			goto Binop;
		case '-':
			i=Isub;
			goto Binop;
		case '*':
			i=Imul;
			goto Binop;
		case '/':
			i=Idiv;
			goto Binop;
		case '%':
			i=Imod;
			goto Binop;
		case '&':
			i=Iand;
			goto Binop;
		case '|':
			i=Ior;
			goto Binop;
		case '^':
			i=Ixor;
			goto Binop;
		case LSH:
			i=Ilsh;
			goto Binop;
		case RSH:
			i=Irsh;
			goto Binop;
		case ANDAND:
			condgen(n->l, n->r, Ijmptrue, Ijmpfalse, 0L, 1L, retain);
			return;
		case OROR:
			condgen(n->l, n->r, Ijmpfalse, Ijmptrue, 1L, 0L, retain);
			return;
		case CAT:
			gen(n->l, 1);
			gen(n->r, 1);
			emit(Icat);
			return;
		case DEL:
			gen(n->l, 1);
			gen(n->r, 1);
			emit(Idel);
			return;
		case PRINT:
			gen(n->l, 1);
			printgen(n->l);
			emit(Isprnt);
			if(!retain)
				emit(Iprint);
			return;
		case SND:
			gen(n->l, 1);
			constgen((long)Cissnd);
			emit(Icommset1);
			emit(Icommcln1);
			gen(n->r, 1);
			if(isptrtype(etypeoft(n->l)->r))
				emit(Isndptr);
			else
				emit(Isnd);
			if(!retain)
				popgen(etypeof(n));
			return;
		case RCV:
			gen(n->l, 1);
			constgen(0L);	/* not Cissnd */
			emit(Icommset1);
			emit(Icommcln1);
			if(!retain)
				popgen(etypeof(n));
			return;
		case '=':
			gen(n->r, 1);
			if(retain)
				dupgen(etypeof(n->r), 1);
			lgen(n->l);
			return;
		case LEN:
			gen(n->l, 1);
			emit(Ilen);
			goto Popit;
		case REF:
			if(isptrtype(etypeof(n->l))){
				gen(n->l, 1);
				emit(Iref);
			}else
				constgen(1L);
			goto Popit;
		case DEF:
			if(retain && n->l->t==NID && isinttype(etypeof(n->l))){
				constgen(1L);
				return;
			}
			/*
			 * don't really need to call lgen1, which will uniquify our
			 * array for us, but it does no harm, and it's easy.
			 */
			lgen1(n->l, Idefauto, Idef, Idefary);
			goto Popit;
		case UMINUS:
			gen(n->l, 1);
			emit(Ineg);
			goto Popit;
		case '~':
			gen(n->l, 1);
			emit(Inot);
			goto Popit;
		case '!':
			gen(n->l, 1);
			emit(Ilnot);
			goto Popit;
		case INC:
			lgen1(n->l, Iincauto, Iinc, Iincary);
			goto Popit;
		case DEC:
			lgen1(n->l, Idecauto, Idec, Idecary);
			goto Popit;
		default:
			panic("can't compile %e expression", n);
		}

	case NExprlist:
		/*
		 * This is an arg or element list; first is pushed last
		 */
		gen(n->r, 1);
		gen(n->l, 1);
		return;
	case NID:
		if(!retain)
			return;
		switch(type_of(n)->o.t){
		case TInt:
		case TChar:
			if(n->o.s->val->isauto){
				emit(Ipushauto);
				emitconst(n->o.s->val->store.off);
			}else{
				emit(Ipush);
				emitconst((long)&n->o.s->val->store.l);
			}
			return;
		case TProg:
		case TArray:
		case TChan:
		case TStruct:
			if(n->o.s->val->isauto){
				emit(Ipushptrauto);
				emitconst(n->o.s->val->store.off);
			}else{
				emit(Ipushptr);
				emitconst((long)&n->o.s->val->store.l);
			}
			return;
		case TUnit:
			if(retain)
				constgen(0L);
			return;
		case TType:
			lerror(n, "attempt to evaluate type variable %m", n);
		default:
			panic("can't compile type %t", n->o.s->val->type);
		}
	case NIf:
		ifgen(n);
		return;
	case NList:
		gen(n->l, 0);
		gen(n->r, 0);
		return;
	case NLoop:
		loopgen(n);
		return;
	case NMk:
		mkgen(n->l, n->r);
		return;
	case NNum:
		if(retain)
			constgen(n->o.l);
		return;
	case NProg:
		if(retain)
			proggen(n->l, n->r);
		return;
	case NResult:
		if(resultloc==0)
			lerror(n, "result not in val");
		gen(n->l, 1);
		emit(Ijmp);
		emitconst((long)(resultloc-here()-1)*WS);
		return;
	case NScope:
		pushscope();
		if(nscope==1){
			int nauto;
			autooffset=0;
			emit(Ipushfp);
			nauto=here();
			emitconst(0L);
			gen(n->l, 0);
			patch((int)nauto, autooffset);
			emit(Ipop);	/* Ipopfp() */
		}else
			gen(n->l, 0);
		scopedecrefgen();
		popscope();
		return;
	case NSelect:
		selgen(n->l);
		return;
	case NSmash:{
		Value *vl, *vr;
		vl=n->l->o.s->val;
		vr=n->r->o.s->val;
		if(vr->type->o.t==TType){
			freenode(vl->type);
			vl->type=dupnode(vr->type);
			return;
		}
		gen(n->r, 1);
		/*
		 * Free old values; tricky: push as int, pop as ptr
		 */
		if(isptrtype(vl->type)){
			if(vl->isauto){
				emit(Ipushauto);
				emitconst(vl->store.off);
			}else{
				emit(Ipush);
				emitconst((long)&vl->store.l);
			}
			emit(Ipopptr);
		}
		if(vl->isauto){
			emit(Istoreauto);
			emitconst(vl->store.l);
			return;
		}
		emit(Istore);
		emitconst((long)&vl->store.l);
		return;
	}
	case NString:
		if(retain){
			emit(Ipushdata);
			emitconst((long)n->o.st);
			emitstore(n->o.st);
			n->o.st->ref++;
		}
		return;
	case NStructref:
		arygen(n->l, n->r, 1, n->o.l);
		return;
	case NSwitch:
		switchgen(n->l, n->r);
		return;
	case NUnit:
		if(retain)
			constgen(0L);
		return;
	case NVal:
		valgen(n->l);
		if(!retain)
			popgen(n->o.n);
		return;
	}
	panic("can't compile node %n", n);
	return;
}
Пример #5
0
void swf_AddButtonLinks(SWF*swf, char stop_each_frame, char events)
{
    int num_frames = 0;
    int has_buttons = 0;
    TAG*tag=swf->firstTag;

    unsigned int checksum = 0;
    while(tag) {
        if(tag->id == ST_SHOWFRAME)
            num_frames++;
        if(tag->id == ST_DEFINEBUTTON || tag->id == ST_DEFINEBUTTON2)
            has_buttons = 1;
	crc32_add_bytes(checksum, tag->data, tag->len);
        tag = tag->next;
    }
    int t = time(0);
    checksum = crc32_add_bytes(checksum, &t, sizeof(t));

    unsigned char h[16];
    unsigned char file_signature[33];
    sprintf((char*)file_signature, "%x", checksum);

    char scenename1[80], scenename2[80];
    sprintf(scenename1, "rfx.MainTimeline_%s", file_signature);
    sprintf(scenename2, "rfx::MainTimeline_%s", file_signature);

    abc_file_t*file = abc_file_new();
    abc_method_body_t*c = 0;
   
    abc_class_t*cls = abc_class_new2(file, scenename2, "flash.display::MovieClip");
  
    TAG*abctag = swf_InsertTagBefore(swf, swf->firstTag, ST_DOABC);
    
    tag = swf_InsertTag(abctag, ST_SYMBOLCLASS);
    swf_SetU16(tag, 1);
    swf_SetU16(tag, 0);
    swf_SetString(tag, scenename1);

    c = abc_class_getstaticconstructor(cls, 0)->body;
    c->old.max_stack = 1;
    c->old.local_count = 1;
    c->old.init_scope_depth = 9;
    c->old.max_scope_depth = 10;

    __ getlocal_0(c);
    __ pushscope(c);
    __ returnvoid(c);

    c = abc_class_getconstructor(cls, 0)->body;
    c->old.max_stack = 3;
    c->old.local_count = 1;
    c->old.init_scope_depth = 10;
    c->old.max_scope_depth = 11;
    
    debugfile(c, "constructor.as");

    __ getlocal_0(c);
    __ pushscope(c);

    __ getlocal_0(c);
    __ constructsuper(c,0);

    if(stop_each_frame || has_buttons) {
        int frame = 0;
        tag = swf->firstTag;
        abc_method_body_t*f = 0; //frame script
        while(tag && tag->id!=ST_END) {
            char framename[80];
            char needs_framescript=0;
            char buttonname[80];
            char functionname[80];
            sprintf(framename, "[packageinternal]rfx::frame%d_%s", frame, file_signature);
            
            if(!f && (tag->id == ST_DEFINEBUTTON || tag->id == ST_DEFINEBUTTON2 || stop_each_frame)) {
                /* make the contructor add a frame script */
                __ findpropstrict(c,"[package]::addFrameScript");
                __ pushuint(c,frame);
                __ getlex(c,framename);
                __ callpropvoid(c,"[package]::addFrameScript",2);

                f = abc_class_method(cls, 0, multiname_fromstring(framename))->body;
                f->old.max_stack = 3;
                f->old.local_count = 1;
                f->old.init_scope_depth = 10;
                f->old.max_scope_depth = 11;
                __ debugfile(f, "framescript.as");
                __ debugline(f, 1);
                __ getlocal_0(f);
                __ pushscope(f);
                if(stop_each_frame) {
                    __ findpropstrict(f, "[package]::stop");
                    __ callpropvoid(f, "[package]::stop", 0);
                }
            }

            if(tag->id == ST_DEFINEBUTTON || tag->id == ST_DEFINEBUTTON2) {
                U16 id = swf_GetDefineID(tag);
                sprintf(buttonname, "::button%d", swf_GetDefineID(tag));
                __ getlex(f,buttonname);
                __ getlex(f,"flash.events::MouseEvent");
                __ getproperty(f, "::CLICK");
                sprintf(functionname, "::clickbutton%d_%s", swf_GetDefineID(tag), file_signature);
                __ getlex(f,functionname);
                __ callpropvoid(f, "::addEventListener" ,2);

                needs_framescript = 1;

                abc_method_body_t*h =
                    abc_class_method(cls, 0, multiname_fromstring(functionname))->body;
                list_append(h->method->parameters, multiname_fromstring("flash.events::MouseEvent"));

                h->old.max_stack = 6;
                h->old.local_count = 2;
                h->old.init_scope_depth = 10;
                h->old.max_scope_depth = 11;
                __ getlocal_0(h);
                __ pushscope(h);

                ActionTAG*oldaction = swf_ButtonGetAction(tag);
                if(oldaction && oldaction->op == ACTION__GOTOFRAME) {
                    int framenr = GET16(oldaction->data);
                    if(!events) {
                        __ findpropstrict(h,"[package]::gotoAndStop");
                        __ pushuint(h,framenr+1);
                        __ callpropvoid(h,"[package]::gotoAndStop", 1);
                    } else {
                        char framename[80];
                        sprintf(framename, "frame%d_%s", framenr, file_signature);
                        __ getlocal_0(h); //this
                        __ findpropstrict(h, "[package]flash.events::TextEvent");
                        __ pushstring(h, "link");
                        __ pushtrue(h);
                        __ pushtrue(h);
                        __ pushstring(h, framename);
                        __ constructprop(h,"[package]flash.events::TextEvent", 4);
                        __ callpropvoid(h,"[package]::dispatchEvent", 1);
                    }
                } else if(oldaction && oldaction->op == ACTION__GETURL) {
                    if(!events) {
                        __ findpropstrict(h,"flash.net::navigateToURL");
                        __ findpropstrict(h,"flash.net::URLRequest");
                        // TODO: target _blank
                        __ pushstring(h,(char*)oldaction->data); //url
                        __ constructprop(h,"flash.net::URLRequest", 1);
                        __ callpropvoid(h,"flash.net::navigateToURL", 1);
                    } else {
                        __ getlocal_0(h); //this
                        __ findpropstrict(h, "[package]flash.events::TextEvent");
                        __ pushstring(h, "link");
                        __ pushtrue(h);
                        __ pushtrue(h);
                        __ pushstring(h,(char*)oldaction->data); //url
                        __ constructprop(h,"[package]flash.events::TextEvent", 4);
                        __ callpropvoid(h,"[package]::dispatchEvent", 1);
                    }
                } else if(oldaction) {
                    fprintf(stderr, "Warning: Couldn't translate button code of button %d to flash 9 abc action\n", id);
                }
                __ returnvoid(h);
                swf_ActionFree(oldaction);
            }
            if(tag->id == ST_SHOWFRAME) {
                if(f) {
                    __ returnvoid(f);
                    f = 0;
                }
                frame++;
            }
            tag = tag->next;
        }
        if(f) {
            __ returnvoid(f);
        }
    }
    __ returnvoid(c);

    tag = swf->firstTag;
    while(tag) {
        if(tag->id == ST_DEFINEBUTTON || tag->id == ST_DEFINEBUTTON2) {
            char buttonname[80];
            sprintf(buttonname, "::button%d", swf_GetDefineID(tag));
            multiname_t*s = multiname_fromstring(buttonname);
            //abc_class_slot(cls, multiname_fromstring(buttonname), s);
            abc_class_slot(cls, multiname_fromstring(buttonname), 
                                multiname_fromstring("flash.display::SimpleButton"));
        }
        tag = tag->next;
    }


    abc_script_t*s = abc_initscript(file);
    c = s->method->body;
    c->old.max_stack = 2;
    c->old.local_count = 1;
    c->old.init_scope_depth = 1;
    c->old.max_scope_depth = 9;

    __ getlocal_0(c);
    __ pushscope(c);
    __ getscopeobject(c, 0);
    __ getlex(c,"::Object");
    __ pushscope(c);
    __ getlex(c,"flash.events::EventDispatcher");
    __ pushscope(c);
    __ getlex(c,"flash.display::DisplayObject");
    __ pushscope(c);
    __ getlex(c,"flash.display::InteractiveObject");
    __ pushscope(c);
    __ getlex(c,"flash.display::DisplayObjectContainer");
    __ pushscope(c);
    __ getlex(c,"flash.display::Sprite");
    __ pushscope(c);
    __ getlex(c,"flash.display::MovieClip");
    __ pushscope(c);
    __ getlex(c,"flash.display::MovieClip");
    __ newclass(c,cls);
    __ popscope(c);
    __ popscope(c);
    __ popscope(c);
    __ popscope(c);
    __ popscope(c);
    __ popscope(c);
    __ popscope(c);
    __ initproperty(c,scenename2);
    __ returnvoid(c);

    //abc_method_body_addClassTrait(c, "rfx:MainTimeline", 1, cls);
    multiname_t*classname = multiname_fromstring(scenename2);
    abc_initscript_addClassTrait(s, classname, cls);
    multiname_destroy(classname);

    swf_WriteABC(abctag, file);
}