Exemple #1
0
/*
	save resource to stream with garbage collection.
	the resources with reference count of zero are not saved.
*/
static __bool _save_res_stream(IF8Stream * str, F8_RESOURCE * res)
{
	__uint itemcount;
	void * itembuf = 0;
	c_bstr_t cbstr;
	ITEMMAP::iterator it;
	__u16 magic = F8_RES_MAGIC;
	ITEMMAP & imap = *res->pItems;

	if(!res->refcount){
		return __false;
	}

	itemcount = imap.size();
	// 2003-11-20, save non-null resources only
	if(itemcount){
		__vcall__(str, put, (str, &magic, sizeof(magic)));
		__vcall__(str, put, (str, (void*)&res->id, sizeof(f8_uuid)));
		__vcall__(str, put, (str, &itemcount, sizeof(itemcount)));

		it = imap.begin();
		while(it != imap.end()){
			cbstr.buffer = (char*)it->first.data();
			cbstr.count = it->first.length();
			bstr_to_stream(&cbstr, str);
			__vcall__(str, put, (str, &it->second.length, sizeof(__uint)));		
			__vcall__(str, put, (str, it->second.buffer, it->second.length));
			it++;
		}
	}

	return __true;
}
Exemple #2
0
/*
	save the instance resource into the stream
*/
static __bool _save_inst_res_proc(ITreeNode * nd, __bool firstVisit, f8_uint _s)
{
	IBlk * blk;
	ICBlk * cblk;
	struct cblk_link_t * lk;
	struct blk_pin_t  * p;
	struct cblk_pin_t * cp;
	IF8Stream * s;

	s = (IF8Stream*)_s;

	blk = __dcast__(ITreeNode, IBlk, nd);
	
	save_res_stream(&blk->uuid, s);

	if(blk->h.magic == CBLK_MAGIC){
		cblk = __dcast__(IBlk, ICBlk, (blk));
		
		lk = ICBlk_first_link(cblk);
		while(lk){
			save_res_stream(&lk->uuid, s);
			lk = ICBlk_next_link(lk);
		}

		p = __vcall__(blk, first_pin, (blk));
		while(p){
			cp = CONTAINING_RECORD(p, struct cblk_pin_t, p);
			save_res_stream(&cp->uuid, s);
			p = __vcall__(blk, next_pin, (p));
		}
	}
/*
if mount_as_child_or_sibling is true, mount as child
else mount as sibling
fails if:
1) mount as sibling but peer has no parent, since allowing this will
incur two or more roots.
2) mount as child but the newcomer has already a parent(you must umount
it from its previous parent first), i.e., only root can be mounted
*/
__bool ITreeNode_mount(ITreeNode * peer, ITreeNode * newcomer, __bool mount_as_child)
{
	__bool ret;
	if(mount_as_child){
		if( newcomer->uplink ){
			ret = __false;
		}else{
			// insert as the last child
			newcomer->uplink = peer;
			if(peer->first_child){
				RtkInsertTailList(&peer->first_child->sibling, &newcomer->sibling);
			}else{
				peer->first_child = newcomer;				
			}
			ret = __true;
		}		
	}else{
		// as sibling
		if( !peer->uplink ){
			ret = __false;
		}else{
			newcomer->uplink = peer->uplink;
			RtkInsertTailList(
				&peer->uplink->first_child->sibling, 
				&newcomer->sibling
				);			
			ret =  __true;
		}
	}
	if(ret){
		__vcall__(newcomer, on_mount, (newcomer));
	}
	return ret;
}
LOCAL int IPeer_write_zero_copy(IPeer * _this,...)
{
	va_list args;
	void * buf=(void*)-1;
	int len,totalLen=0;
	char rtu[PEER_RTU];
	char *p;

	va_start(args, _this);
	p=rtu;
	while(buf){
		buf = va_arg(args, void *);
		len = va_arg(args, int);
		if(buf){
			if(len+totalLen <= PEER_RTU){
				memcpy(p, buf, len);
				p += len;
				totalLen += len;
			}else{
				return F8_BUFFER_TOO_SMALL;
			}
		}
	}
	return __vcall__(_this, write, (_this, rtu, totalLen));
}
static __bool _save_var(f8_uint context, const hash_key_t * k, const hash_val_t v)
{
	IF8Stream * s;
	struct blk_var_t * nv;
	s = (IF8Stream*)context;
	nv = (struct blk_var_t*)v;
	if(!__vcall__(s, put, (s, nv, sizeof(struct blk_var_t)))){
		return __false;
	}
	return __true;
}
Exemple #6
0
LIBCOBJ_API __bool bstr_from_stream(struct c_bstr_t * b, IF8Stream * s)
{
	if(__vcall__(s, get, (s, &b->count, sizeof(b->count))) != sizeof(b->count)){
		return __false;
	}
	b->buffer = c_alloc_str(b->count);
	if(!b->buffer){
		return __false;
	}
	if(__vcall__(s, get, (s, b->buffer, b->count + 1)) != b->count + 1){
		c_free_str(b->buffer);
		b->buffer = 0;
		return __false;
	}
	if(b->buffer[b->count] != '\0'){
		c_free_str(b->buffer);
		b->buffer = 0;
		return __false;
	}
	return __true;
}
void CRegRequirementList::Add(
	struct blk_pin_t * p, 
	struct mem_addr_t * addr, 
	int length
	)
{
	reg_item	item;
	item.owner = p;
	item.addr = *addr;
	item.length = length;
	item.blk_id = p->blk->uuid;
	item.pin_id = __vcall__(p->blk, id_by_pin, (p));
	m_rlist.insert(m_rlist.begin(), item);
}
__uint ITreeNode_umount_children(ITreeNode * __this)
{
	__uint res = 0;
	ITreeNode *nd, *next=0;
	
	nd = __this->first_child;
	if(nd){
		next = ITreeNode_next(nd);
	}
	
	while(nd){
		res += ITreeNode_umount_children(nd);
		__vcall__(nd, before_umount, (nd));
		ITreeNode_umount(nd);
		__vcall__(nd, after_umount, (nd));
		res++;
		nd = next;
		if(nd){
			next = ITreeNode_next(nd);
		}
	}
	
	return res;
}
Exemple #9
0
static int UTILS_API _e_file(
	const char * szBaseDir,
	const char * szFullPath,
	const char * szRelativePath,
	const void * pvSearchContext
	)
{
	IBlk * blk;
	char buf[128];
	IFileStream *fs;
	IF8Stream *s;
	int roffset;

	fs = IFileStream_from_file(szFullPath, "rb");
	if(!fs){
		return 1;
	}
	s = __ucast__(IFileStream, IF8Stream, (fs));
	blk = IBlk_from_stream(s);
	if(!blk){
		__delete__(fs);
		return 1;
	}
	roffset = __vcall__(s, tell, (s));
	load_res_stream(s);
	probe_blk_resources(blk);
	
	fprintf(fdb, 
		"%d=%s,%c%c,%s", 
		count,
		IBlk_class_name(blk),
		blk->h.magic >> 8,
		blk->h.magic & 0xff,
		szRelativePath
		);
	f8_uuid_to_string(&blk->h.uuid, buf, sizeof(buf));
	fprintf(fdb, ",%s", buf);
	fprintf(fdb, ",%d", roffset);
	fprintf(fdb, "\n");
	
	delete_blk(blk);
	__delete__(fs);

	count++;
	return 1;
}
Exemple #10
0
static __inline struct blk_pin_t * _extract_pin(
	struct kernel_t * kernel, 
	IMemStream *s)
{
	IBlk * blk;
	__u16 pid;

	blk = _extract_blk_by_uuid(kernel, s);
	if(!blk){
		return 0;
	}
	if(!_extract_u16(s, &pid)){
		return 0;
	}

	return __vcall__(blk, pin_by_id, (blk, pid));
}
Exemple #11
0
/*
	load resources in the stream, note the reference
	count of the resources are not affected, or set
	to zero if not already present.
*/
F8RES_API __bool load_res_stream(
	IF8Stream * s
	)
{
	F8_RESOURCE *h;
	
	do{
		h = _load_res_stream(s);
	}while(h);
	
	/* we should have consumed all the stream contents */
	if(!__vcall__(s, eos, (s))){
		return __false;
	}
	
	return __true;
}
Exemple #12
0
void ki_halt(struct kernel_t * kernel, f8_status code)
{
	f8_u32 c1,c2,c3;

	c1=c2=c3=0;
	if(kernel->current_blk){
		c1 = (f8_u32)(kernel->current_blk->uuid >> 32);
		c2 = (f8_u32)(kernel->current_blk->uuid & 0xffffffff);
		if(kernel->current_pin){
			c3 = __vcall__(
				kernel->current_blk, 
				id_by_pin, 
				(kernel->current_pin)
				);
		}else{
			c3 = -1;
		}
	}
Exemple #13
0
ICBlk * ICBlk_from_stream	(IF8Stream * s)
{
    ICBlk * blk;
    IBlk  * b;

    blk = mm_alloc(g_hBlkHeap, sizeof(ICBlk), 0);
    if(!blk) {
        return 0;
    }

    __create__(ICBlk, blk);

    b = __ucast__(ICBlk, IBlk, blk);

    if(!__vcall__(b, load, (b, s))) {
        delete_blk(b);
        return 0;
    }
    return blk;
}
__bool CRegRequirementList::Alloc(struct blk_pin_t * p)
{
	reg_item	item;

	p->u2.mem_addr.section = ke_section_by_type(p->type);
	item.length = _type_size(p->type);

	if(!alloc_reg((void*)p, &p->u2.mem_addr, item.length, PIN_MAGIC)){
		m_errcode = F8_LOW_REGISTERS;
		return __false;
	}

	item.blk_id = p->blk->uuid;
	item.pin_id = __vcall__(p->blk, id_by_pin, (p));
	item.owner = p;
	item.addr = p->u2.mem_addr;
	m_rlist.insert(m_rlist.end(), item);

	return __true;
}
void CRegRequirementList::Commit(__bool bCharge)
{
	reglist::iterator it;
	varlist::iterator vit;
	reg_item	*item;
	var_item	*vitem;
	int i;

	for(i = m_rlist.size(), it = m_rlist.begin(); i; i--, it++){
		item = &(*it);
		/*
			fixup owner
		*/
		if(item->blk_id != BLK_ID_NONE){
			IBlk * blk;
			blk = ke_get_blk(proxy_adapter->kernel, &item->blk_id);
			assert(blk);
			item->owner = __vcall__(blk, pin_by_id, (blk, item->pin_id));
			assert(item->owner);
		}
		set_address_owner(
			item->owner, 
			&item->addr, 
			item->length, 
			PIN_MAGIC,
			bCharge
			);
	}

	for(i = m_vlist.size(), vit = m_vlist.begin(); i; i--, vit++){
		vitem = &(vit->second);
		vitem->var->blk = ke_get_blk(
			proxy_adapter->kernel, 
			&vitem->var->blk->uuid
			);
		vitem->var->ref_count += vitem->ref_count;
	}

	m_rlist.clear();
	m_vlist.clear();
}
Exemple #16
0
LIBCOBJ_API void bstr_to_stream(struct c_bstr_t * b, IF8Stream *s)
{
	__vcall__(s, put, (s, &b->count, sizeof(b->count)));
	__vcall__(s, put, (s, b->buffer, b->count + 1));
}
Exemple #17
0
/*
	construct a resource object in memory from a stream
	the stream is composed of:
	1) a magic
	2) uuid
	3) item count
	4) array of items

	NOTE!! 
	1) On success, the resource item is not reference counted. 
	If the client won't addref on the loaded resource, then the 
	item is exposed to the garbage collector.
	More exactly, this proc won't addref on the resource when
	the resource already exists.
*/
static F8_RESOURCE * _load_res_stream(IF8Stream * str)
{
	__u16	magic;
	RESMAP::iterator it;
	__u32 itemcount;
	c_bstr_t cbstr;
	f8_uuid id;
	__int	length;
	void	* buffer;
	F8_RESOURCE * res;
	__bool ret;

	// DEBUG_PRINTF(("stream %08x\n", __vcall__(str, tell, (str))));
	
	if(!__vcall__(str, get, (str, &magic, sizeof(magic)))){
		return 0;
	}

	if(magic != F8_RES_MAGIC && magic != F8_RES_MAGIC_2){
		__vcall__(str, seek, (str, -sizeof(magic), SEEK_CUR));
		return 0;
	}

	if(!__vcall__(str, get, (str, &id, sizeof(id)))){
		return 0;
	}

	res = create_resource_bibibobo(&id, __false);
	if(!res){
		return 0;
	}
	
	/* the resource has not been loaded yet */
	if(!__vcall__(str, get, (str, &itemcount, sizeof(itemcount)))){
		return 0;
	}

	if(res->refcount){
		/* note if the resource is already present we silently
		eat the stream without modifing the in-memory version
		*/
		for(; itemcount; itemcount--){
			if(!__vcall__(str, get, (str, &cbstr.count, sizeof(cbstr.count)))){
				goto __failed;
			}
			__vcall__(str, seek, (str, cbstr.count, SEEK_CUR));
			if(!__vcall__(str, get, (str, &length, sizeof(length)))){
				goto __failed;
			}
			__vcall__(str, seek, (str, length, SEEK_CUR));
		}	
	}else{
		for(; itemcount; itemcount--){	
			if(!bstr_from_stream(&cbstr, str)){
				goto __failed;
			}

			if(!__vcall__(str, get, (str, &length, sizeof(length)))){
				goto __failed;
			}
			if(length){
				buffer = __malloc__(length);
				if(!buffer){
					goto __failed;
				}
				if(!__vcall__(str, get, (str, buffer, length))){
					goto __failed;
				}
			}else{
				buffer = 0;
			}
			
			ret = set_res_buf(&id, buffer, length, cbstr.buffer);
			__free__(buffer);
			c_free_bstr(&cbstr);
			if(!ret){
				goto __failed;
			}
		}
	}
	return res;	

__failed:
	/* the unload_resource will decrease the refcount */
	res->refcount++;
	unload_resource(&id);
	
	return 0;
}
static void dumpBblk(IBlk * b, FILE * of)
{
	const char * name;
	char path[F8_MAX_PATH];
	char buf[1024];
	char idName[128];
	struct blk_ent_t be;
	struct blk_pin_t * p;

	*buf=0;
	if(!(parent_blk(b)->h.flags & BLK_F_READONLY)){
		name = IBlk_name(b);
		IBlk_path_by_blk(parent_blk(b), path, sizeof(buf));
		if(blklib_query(&b->h.uuid, &be)){
			sprintf(buf, "mount  path=\"%s\" type=\"%s.%s\" name=\"%s\"", path, be.dir, be.name, name);
		}else{
			f8_uuid_to_string(&b->h.uuid, idName, sizeof(idName));
			sprintf(buf, "mount  path=\"%s\" id=%s name=\"%s\" ", path, idName, name);
		}
		if(of==stdout)
			utils_trace("%s\n", buf);
		else
			fprintf(of, "%s\n", buf);
		IBlk_path_by_blk(b, path, sizeof(path));
		sprintf(buf, "place block \"%s\" (%d,%d)", path, get_res_int(&b->uuid, "x", 0), get_res_int(&b->uuid, "y", 0));
		if (of==stdout)
			utils_trace("%s\n", buf);
		else
			fprintf(of, "%s\n", buf);		
	}
	
	for(p = __vcall__(b, first_pin, (b)); p; p = __vcall__(b, next_pin, (p))){
		if(p->_class != PIN_CLASS_DI && p->_class != PIN_CLASS_DO){
			continue;
		}
		IBlk_path_by_pin(p, path, sizeof(path));
		// dump binding
		*buf = 0;
		if(p->binding == PIN_B_CONST){
			switch(p->type){
			case  PIN_T_INTEGER	:
				if(p->dp->u.d.i32 != 0){
					sprintf(buf, "bind \"%s\" %d", path, p->dp->u.d.i32);
				}
				break;
			case  PIN_T_BOOL		:
				if(p->dp->u.d.ui8 != 0){
					sprintf(buf, "bind \"%s\" %d", path, p->dp->u.d.ui8);
				}
				break;
			case  PIN_T_FLOAT		:
				if(p->dp->u.d.flt != 0){
					sprintf(buf, "bind \"%s\" %f", path, p->dp->u.d.flt);
				}
				break;
			case  PIN_T_BYTE		:
				if(p->dp->u.d.ui8 != 0){
					sprintf(buf, "bind \"%s\" %d", path, p->dp->u.d.ui8);
				}
				break;
			case  PIN_T_WORD		:
				if(p->dp->u.d.ui16 != 0){
					sprintf(buf, "bind \"%s\" %d", path, p->dp->u.d.ui16);
				}
				break;
			case  PIN_T_DOUBLE	:
				if(p->dp->u.d.dbl != 0){
					sprintf(buf, "bind \"%s\" %.15f", path, p->dp->u.d.dbl);
				}
				break;
			case  PIN_T_DATE		:
				if(fabs(p->dp->u.d.dbl) > 1e-9){
					if(p->dp->u.d.dbl > 2.0){
						sprintf(buf, "bind \"%s\" t#%fs", path, p->dp->u.d.dbl);
					}else{
						sprintf(buf, "bind \"%s\" t#%fms", path, p->dp->u.d.dbl*1000);
					}
				}
				break;
			case  PIN_T_CHAR		:
				if(p->dp->u.d.i8 != 0){
					sprintf(buf, "bind \"%s\" %d", path, p->dp->u.d.i8);
				}
				break;
			case  PIN_T_SHORT		:
				if(p->dp->u.d.i16 != 0){
					sprintf(buf, "bind \"%s\" %d", path, p->dp->u.d.ui16);
				}
				break;
			case  PIN_T_DWORD		:
				if(p->dp->u.d.ui32 != 0){
					sprintf(buf, "bind \"%s\" %d", path, p->dp->u.d.ui32);
				}
				break;
			}
		}else {
			struct blk_var_t * v;
			v = query_var_by_pin(p);
			if(v){
				char vpath[F8_MAX_PATH];
				IBlk_path_by_blk(v->blk, vpath, sizeof(vpath));
				sprintf(buf, "bind \"%s\" %s.%s", path, vpath, v->name);
				// on_bind
			}
		}

		if(*buf){
			if(of==stdout)
				utils_trace("%s\n", buf);
			else
				fprintf(of, "%s\n", buf);
		}
		
		if(p->type==PIN_T_BOOL && (p->flags & PIN_F_INVERTED)){
			sprintf(buf, "invert \"%s\"", path);
			if(of==stdout)
				utils_trace("%s\n", buf);
			else
				fprintf(of, "%s\n", buf);
		}
		
	}
}
/*
	finding out registers usage info for the block hive
*/
static __bool _gather_reg_usage(ITreeNode * nd, __bool firstVisit, __uint context)
{
	IBlk * b;
	struct blk_pin_t *p, *rp;
	int length;
	CRegRequirementList * req;
	struct blk_var_t * var;
	char pName[F8_MAX_PATH];

	b = __dcast__(ITreeNode, IBlk, nd);

	req = (CRegRequirementList *)context;

	if(b->h.magic == CBLK_MAGIC && req->m_bGatherForDelete){
		enum_variables(b, _e_var, (__uint)req);
	}	
	
	for(p = __vcall__(b, first_pin, (b)); p; p = __vcall__(b, next_pin, (p))){
		/*
			if the pin is exported, then the variable reference or memory address
			assignment is counted on the exported pins
		*/
		if(p->ulink){
			continue;
		}
		rp = IBlk_real_pin(p);
		if(rp->_class != PIN_CLASS_DI && rp->_class != PIN_CLASS_DO){
			continue;
		}
		if(rp->binding != PIN_B_MEMORY){
			continue;
		}
		length = _type_size(rp->type);
		var = (blk_var_t*)query_var_by_pin(p);
		if(var){
			req->Add(var);
		}else{
			if(rp->_class == PIN_CLASS_DI){
				if(RtkIsTripleListEmpty(&rp->u1.link)){
					/*
					a data input pin can have a memory address only in
					two cases: 1) linked. or 2) connected with variable.
					*/
					IBlk_path_by_pin(p, pName, sizeof(pName));
					utils_error(
						"%s - DI pin address %%%d%05d incorrect.\n", 
						pName, 
						rp->u2.mem_addr.section, 
						rp->u2.mem_addr.addr
						);
					req->m_errcode = F8_INVALID_DATA;
				}
			}else{
				if(!is_address_valid(proxy_adapter->kernel, rp, &rp->u2.mem_addr)){
					req->m_errcode = F8_INVALID_DATA;
					IBlk_path_by_pin(p, pName, sizeof(pName));
					utils_error(
						"%s - DO pin address %%%d%05d incorrect.\n", 
						pName, 
						rp->u2.mem_addr.section, 
						rp->u2.mem_addr.addr
						);
				}else{
					req->Add(rp, &rp->u2.mem_addr, length);
				}
			}
		}
	}

	return __true;
}
/*
	expand or shrink section memory size

	usage

	memsize [section_id] [size]
*/
int on_memsize(char *v, void *k)
{
	int i;
	CArgs a;
	_shproc_prolog_();

	parse_arg_exA(v, &a, FS);
	if(a.argc == 1){
		for(i=0; i<KERN_NUM_SECTIONS; i++){
			utils_trace("memsize %d %d \n", i, g_regmap[i].total_items);
		}
	}else if(a.argc == 3){
		int newSize;
		i = atoi(a.argv[1]);
		newSize = atoi(a.argv[2]);
		if(newSize < g_regmap[i].total_items){
			// memory shrinking is not implemented
			utils_error("memory shrinking is dangerous.\n");
			// return F8_UNIMPLEMENTED;
		}
		if(newSize > MAP_ENTRIES){
			return F8_LOW_REGISTERS;
		}

		if(proxy_adapter->flags & ADAPTER_F_ONLINE){
			return F8_INVALID_OPERATION;
		}
		/*
			load memory configuration
		*/
		struct ctrller_config cfg;
		cmd.cmd = F8_GET_SYS_CONFIG;
		cmd.osize = sizeof(struct ctrller_config);
		cmd.obuffer = (char *)&cfg;
		__vcall__(
			proxy_adapter,
			exec,
			(proxy_adapter, &cmd, 5000)
			);
		if(!successful){
			return cmd.retcode;
		}

		cfg.x_mem_sizes[i]=newSize;
		cmd.cmd=F8_SET_SYS_CONFIG;
		cmd.isize=sizeof(cfg);
		cmd.osize=0;
		cmd.ibuffer=&cfg;
		__vcall__(
			proxy_adapter,
			exec,
			(proxy_adapter, &cmd, 5000)
			);
		if(!successful){
			return cmd.retcode;
		}
			
		g_regmap[i].free_items += newSize - g_regmap[i].total_items;
		g_regmap[i].total_items = newSize;
	}
	return F8_SUCCESS;
}
Exemple #21
0
static __bool ICBlk_save(IBlk * _this, IF8Stream * s)
{
    IBlk * sb;
    struct cblk_link_t * l;
    struct cblk_pin_t  * p;
    union blk_pindef_t pd;
    ICBlk * cblk;

    cblk = __dcast__(IBlk, ICBlk, _this);

    // write header
    __vcall__(s, put, (s, &_this->h, sizeof(_this->h)));

    // write guid
    __vcall__(s, put, (s, &_this->uuid, sizeof(f8_uuid)));

    // write sub-blocks
    sb = first_subblk(_this);
    while(sb) {
        if(!__vcall__(sb, save, (sb, s))) {
            return __false;
        }
        sb = next_blk(sb);
    }

    // write link-defs
    l = _first_link(cblk);
    while(l) {
        __vcall__(s, put, (s, &l->uuid, sizeof(l->uuid)));
        pd.id.bid = IBlk_id_by_blk(l->s.pin->blk);
        pd.id.pid = __vcall__(l->s.pin->blk, id_by_pin, (l->s.pin));
        __vcall__(s, put, (s, &pd, sizeof(pd)));
        pd.id.bid = IBlk_id_by_blk(l->t.pin->blk);
        pd.id.pid = __vcall__(l->t.pin->blk, id_by_pin, (l->t.pin));
        __vcall__(s, put, (s, &pd, sizeof(pd)));
        l = _next_link(l);
    }

    // write pins
    p = _first_pin(cblk);
    while(p) {
        __vcall__(s, put, (s, &p->uuid, sizeof(p->uuid)));
        pd.id.bid = IBlk_id_by_blk(p->p.u1.x.id.llink->blk);
        pd.id.pid = __vcall__(p->p.u1.x.id.llink->blk, id_by_pin, (p->p.u1.x.id.llink));
        __vcall__(s, put, (s, &pd, sizeof(pd)));
        p = _next_pin(cblk, p);
    }

    return __true;
}
/*
	patch the memory address in a block hive, and remember
	all register allocated.
*/
static __bool _alloc_reg_proc(ITreeNode * nd, __bool firstVisit, __uint context)
{
	IBlk * b, *pb;
	struct blk_pin_t *p, *rp;
	CRegRequirementList * req;
	char path[1024];
	blk_var_t * v;

	req = (CRegRequirementList*)context;
	b = __dcast__(ITreeNode, IBlk, nd);
	
	pb = parent_blk(b);
		
	for(p = __vcall__(b, first_pin, (b)); 
		p; 
		p = __vcall__(b, next_pin, (p))
	){
		if(p->_class == PIN_CLASS_EI || p->_class == PIN_CLASS_EO){
			continue;
		}

		if(p->ulink){
			// postpone register allocation until the outmost 
			// parent block is being processed
			continue;
		}

		// ok, do allocation
		rp = IBlk_real_pin(p);
		if(rp->binding == PIN_B_CONST){
			if(rp->_class == PIN_CLASS_DI){
				memcpy(rp->dp, p->dp, _type_size(rp->type));
				continue;
			}else{
				req->m_errcode = F8_INVALID_DATA;
				return __false;
			}			
		}else if(rp->binding != PIN_B_MEMORY){
			req->m_errcode = F8_INVALID_DATA;
			return __false;
		}

		if(pb && p->u2.mem_addr.section == MEM_SECTION_VAR){
			//
			// the pin references a variable
			//
			if(v = (blk_var_t * )query_var_by_id(pb, p->u2.mem_addr.addr)){
				// 
				// note!! address is fixed on real pin
				//
				if(v->type != rp->type){
					req->m_errcode = F8_INVALID_DATA;
					return __false;
				}
				rp->u2.mem_addr = v->addr;
				req->Add(v);
			}else{
				IBlk_path_by_pin(p, path, sizeof(path));
				utils_error(
					"%s references undefined variable %d.\n", 
					path, 
					p->u2.mem_addr.addr
					);
				req->m_errcode = F8_UNRESOLVED_REFERENCES;
				return __false;
			}
		}else{
			//
			// the pin has an address on its own
			//
			if(!req->Alloc(rp)){
				return __false;
			}
		}
	}

	return __true;
}
Exemple #23
0
/*
	ICBlk::load(IF8Stream * s)
	this will construct an in-memory composite block object.
	the most exciting part of F8 controller program.
*/
static __bool ICBlk_load(IBlk * blk, IF8Stream * s)
{
    ICBlk * cblk;
    struct blk_hdr_t * h, _h;
    int i;
    IBlk * sb;
    union blk_pindef_t pd, ps, pt;
    f8_uuid uuid;

    cblk = __dcast__(IBlk, ICBlk, blk);
    h = &_h;

    if(__vcall__(s, get, (s, h, sizeof(struct blk_hdr_t)))
            !=
            sizeof(struct blk_hdr_t)
      ) {
        return __false;
    }

    blk->h = *h;
    blk->h.u1.n_subblocks = 0;
    blk->h.u2.n_links = 0;
    blk->h.n_pins = 0;

    if(!__vcall__(s, get, (s, &blk->uuid, sizeof(blk->uuid)))) {
        goto __failed;
    }

    /*
    	load sub-blocks
    */
    for(i=0; i<h->u1.n_subblocks; i++) {
        sb = IBlk_from_stream(s);
        if(!sb) {
            goto __failed;
        }
        if(!ICBlk_add_blk(cblk, sb)) {
            delete_blk(sb);
            return __false;
        }
    }

    /*
    	load links
    */
    for(i=0; i<h->u2.n_links; i++) {
        if(!__vcall__(s, get, (s, &uuid, sizeof(uuid)))) {
            goto __failed;
        }

        if(!__vcall__(s, get, (s, &ps, sizeof(union blk_pindef_t)))) {
            goto __failed;
        }

        if(!__vcall__(s, get, (s, &pt, sizeof(union blk_pindef_t)))) {
            goto __failed;
        }

        locate_pin(blk, ps);
        locate_pin(blk, pt);

        if(!ps.pin || !pt.pin) {
            goto __failed;
        }

        if(!ICBlk_link(&uuid, ps.pin, pt.pin)) {
            goto __failed;
        }
    }

    /*
    	load exports
    */
    for(i=0; i<h->n_pins; i++) {
        if(!__vcall__(s, get, (s, &uuid, sizeof(uuid)))) {
            goto __failed;
        }

        if(!__vcall__(s, get, (s, &pd, sizeof(union blk_pindef_t)))) {
            goto __failed;
        }

        locate_pin(blk, pd);
        if(!pd.pin) {
            return __false;
        }

        if(!ICBlk_add_pin(&uuid, pd.pin)) {
            return __false;
        }
    }

    return __true;

__failed:
    return __false;
}
Exemple #24
0
/*
	errors checked in this procedure
	1) unattached DI with memory binding
	2) DO without memory binding
	3) DO with incorrect memory address
	4) DO with conflicting address
	5) multiple assignments of a variable
*/
__bool CErrorDetector::_fixup_pins(ITreeNode * nd)
{
	IBlk * b;
	struct blk_pin_t * p;
	
	void * o;
	const struct blk_var_t * var;
	struct blk_pin_t * rp;
	int length;

	b = __dcast__(ITreeNode, IBlk, nd);
	for(p = __vcall__(b, first_pin, (b)); p; p = __vcall__(b, next_pin, (p))){
		if(p->ulink){
			continue;
		}

		rp = IBlk_real_pin(p);
		
		if(!(rp->_class == PIN_CLASS_DI || rp->_class == PIN_CLASS_DO)){
			continue;
		}

		if(rp->_class == PIN_CLASS_DO && rp->binding != PIN_B_MEMORY){
			// invalid binding
			CInvalidAddress ia;
			ia.magic = PIN_MAGIC;
			ia.o = rp;
			ia.a = 0; /* DO without MEMORY BINDING */
			m_invalidAddress.insert(m_invalidAddress.end(), ia);
		}

		if(rp->binding != PIN_B_MEMORY){
			continue;
		}

		length = _type_size(rp->type);
		var = (blk_var_t*)query_var_by_pin(p);
		if(!var){
			if(rp->_class == PIN_CLASS_DI){
				if(RtkIsTripleListEmpty(&rp->u1.link)){
					CInvalidAddress ia;
					ia.magic = PIN_MAGIC;
					ia.o = rp;
					ia.a = 1; /* unattached DI with memory binding */
					m_invalidAddress.insert(m_invalidAddress.end(), ia);
				}
			}else{
				if(!is_address_valid(proxy_adapter->kernel, rp, &rp->u2.mem_addr)){
					CInvalidAddress ia;
					ia.magic = PIN_MAGIC;
					ia.o = rp;
					ia.a = 2; /* invalid address */
					m_invalidAddress.insert(m_invalidAddress.end(), ia);
				}
				CAddressConflit ac;
				/* check conflicts */
				o = get_address_owner(&rp->u2.mem_addr, 1, &ac.magic2);
				if(o == rp){
					continue;
				}
				ac.magic1 = PIN_MAGIC;
				ac.o1 = rp;
				ac.o2 = o;
				m_addrConflicts.insert(m_addrConflicts.end(), ac);
			}
		}else{
			// the error is credited to the variable, not check here
		}
	}

	return __true;
}