Ejemplo n.º 1
0
/**
	Create a client side ENetHost with 'connections' max outgoing connections
	using the specified bandwidth limits.
**/
static value udpr_client_create(value connections, value incoming, value outgoing)
{
	ENetHost *h;
	h = enet_host_create(	NULL,
							(size_t)val_int(connections), 		/* number of clients and/or outgoing connections */
							(enet_uint32)val_int32(incoming),	/* amount of incoming bandwidth in Bytes/sec */
							(enet_uint32)val_int32(outgoing));
	if(h == NULL)
		//val_throw(alloc_string("Host creation failure"));
		neko_error();
	value v = alloc_abstract(k_udprhost,h);
	val_gc(v, destroy_enethost);
	return v;
}
Ejemplo n.º 2
0
EXTERN int val_compare( value a, value b ) {
	char tmp_buf[32];
	switch( C(val_type(a),val_type(b)) ) {
	case C(VAL_INT,VAL_INT):
		return icmp(val_int(a),val_int(b));
	case C(VAL_INT32,VAL_INT):
		return icmp(val_int32(a),val_int(b));
	case C(VAL_INT,VAL_INT32):
		return icmp(val_int(a),val_int32(b));
	case C(VAL_INT32,VAL_INT32):
		return icmp(val_int32(a),val_int32(b));
	case C(VAL_INT,VAL_FLOAT):
		return fcmp(val_int(a),val_float(b));
	case C(VAL_INT32,VAL_FLOAT):
		return fcmp(val_int32(a),val_float(b));
	case C(VAL_INT,VAL_STRING):
		return scmp(tmp_buf,sprintf(tmp_buf,"%d",val_int(a)),val_string(b),val_strlen(b));
	case C(VAL_INT32,VAL_STRING):
		return scmp(tmp_buf,sprintf(tmp_buf,"%d",val_int32(a)),val_string(b),val_strlen(b));
	case C(VAL_FLOAT,VAL_INT):
		return fcmp(val_float(a),val_int(b));
	case C(VAL_FLOAT,VAL_INT32):
		return fcmp(val_float(a),val_int32(b));
	case C(VAL_FLOAT,VAL_FLOAT):
		return fcmp(val_float(a),val_float(b));
	case C(VAL_FLOAT,VAL_STRING):
		return scmp(tmp_buf,sprintf(tmp_buf,FLOAT_FMT,val_float(a)),val_string(b),val_strlen(b));
	case C(VAL_STRING,VAL_INT):
		return scmp(val_string(a),val_strlen(a),tmp_buf,sprintf(tmp_buf,"%d",val_int(b)));
	case C(VAL_STRING,VAL_INT32):
		return scmp(val_string(a),val_strlen(a),tmp_buf,sprintf(tmp_buf,"%d",val_int32(b)));
	case C(VAL_STRING,VAL_FLOAT):
		return scmp(val_string(a),val_strlen(a),tmp_buf,sprintf(tmp_buf,FLOAT_FMT,val_float(b)));
	case C(VAL_STRING,VAL_BOOL):
		return scmp(val_string(a),val_strlen(a),val_bool(b)?"true":"false",val_bool(b)?4:5);
	case C(VAL_BOOL,VAL_STRING):
		return scmp(val_bool(a)?"true":"false",val_bool(a)?4:5,val_string(b),val_strlen(b));
	case C(VAL_STRING,VAL_STRING):
		return scmp(val_string(a),val_strlen(a),val_string(b),val_strlen(b));
	case C(VAL_BOOL,VAL_BOOL):
		return (a == b) ? 0 : (val_bool(a) ? 1 : -1);
	case C(VAL_OBJECT,VAL_OBJECT):
		if( a == b )
			return 0;
		{
			value tmp = val_field(a,id_compare);
			if( tmp == val_null )
				return invalid_comparison;
			a = val_callEx(a,tmp,&b,1,NULL);
		}
		if( val_is_int(a) )
			return val_int(a);
		return invalid_comparison;
	default:
		if( a == b )
			return 0;
		return invalid_comparison;
	}
}
Ejemplo n.º 3
0
/**
	Set the in and out speeds of a host in Bytes per second.
**/
static value udpr_setrate(value o, value in, value out)
{
    if( !val_is_abstract(o) || !val_is_kind(o,k_udprhost) )
		neko_error();
	enet_host_bandwidth_limit((ENetHost *)val_data(o), (enet_uint32)val_int32(in), (enet_uint32)val_int32(out));
	return val_true;
}
Ejemplo n.º 4
0
/**
	socket_send_to : 'socket -> buf:string -> pos:int -> length:int -> addr:{host:'int32,port:int} -> int
	<doc>
	Send data from an unconnected UDP socket to the given address.
	</doc>
**/
static value socket_send_to( value o, value data, value pos, value len, value vaddr ) {
	int p,l,dlen;
	value host, port;
	struct sockaddr_in addr;
	val_check_kind(o,k_socket);
	val_check(data,string);
	val_check(pos,int);
	val_check(len,int);
	val_check(vaddr,object);
	host = val_field(vaddr, f_host);
	port = val_field(vaddr, f_port);
	val_check(host,int32);
	val_check(port,int);
	p = val_int(pos);
	l = val_int(len);
	dlen = val_strlen(data);
	memset(&addr,0,sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(val_int(port));
	*(int*)&addr.sin_addr.s_addr = val_int32(host);
	if( p < 0 || l < 0 || p > dlen || p + l > dlen )
		neko_error();
	POSIX_LABEL(send_again);
	dlen = sendto(val_sock(o), val_string(data) + p , l, MSG_NOSIGNAL, (struct sockaddr*)&addr, sizeof(addr));
	if( dlen == SOCKET_ERROR ) {
		HANDLE_EINTR(send_again);
		return block_error();
	}
	return alloc_int(dlen);
}
Ejemplo n.º 5
0
/**
	math_abs : number -> number
	<doc>Return absolute value of a number</doc>
**/
static value math_abs( value n ) {
	switch( val_type(n) ) {
	case VAL_INT:
		return alloc_int( abs(val_int(n)) );
	case VAL_INT32:
		return alloc_int32( abs(val_int32(n)) );
	case VAL_FLOAT:
		return alloc_float( fabs(val_float(n)) ); 
	default:
		neko_error();
	}
}
Ejemplo n.º 6
0
	// TODO: check if this is right
	// sync with udpr_connect() below
static value populate_address(ENetAddress *a, value ip, value port) {
	if(!val_is_null(ip))
		val_check(ip,int32);
	val_check(port,int);

	if(!val_is_null(ip) && val_int32(ip) != 0) {
		a->host = val_int32(ip);
		//a->host = htonl(val_int32(ip));
	}
	else {
#ifdef ENET_DEBUG
		fprintf(stderr, "populate_address: null ip\n");
#endif
		a->host = ENET_HOST_ANY;
	}
	a->port = val_int(port); //htons(val_int(port))
#ifdef ENET_DEBUG
	fprintf(stderr, "populate_address: %x:%u from %x:%u\n", a->host, a->port, val_is_null(ip)?0:val_int32(ip),val_int(port));
#endif
	return val_true;
}
Ejemplo n.º 7
0
/**
        socket_bind : host : int32 -> port:int -> connections:int -> incoming:int32 -> outgoing:int32 -> bool
        <doc>Bind a UDPR socket for server usage on the given host and port, with max connections,
        incoming bandwidth limited to bytes per second or 0 for unlimited, outgoing also. Host may be
        val_type_null, in which case the binding is to ENET_HOST_ANY
        </doc>
**/
static value udpr_bind( value ip, value port, value connections, value incoming, value outgoing ) {
	ENetAddress address;
	ENetHost *s;
	val_check(connections,int);
	val_check(incoming,int32);
	val_check(outgoing,int32);
	if(populate_address(& address, ip, port) != val_true)
		neko_error();

	s = enet_host_create(	&address,
							(size_t)val_int(connections), 		/* number of clients and/or outgoing connections */
							(enet_uint32)val_int32(incoming),	/* amount of incoming bandwidth in Bytes/sec */
							(enet_uint32)val_int32(outgoing));
	if(s == NULL)
		neko_error();
	value v = alloc_abstract(k_udprhost,s);
	val_gc(v, destroy_enethost);
#ifdef ENET_DEBUG
	fprintf(stderr, "udpr_bind: complete\n");
#endif
	return v;
}
Ejemplo n.º 8
0
/**
	socket_connect : 'socket -> host:'int32 -> port:int -> void
	<doc>Connect the socket the given [host] and [port]</doc>
**/
static value socket_connect( value o, value host, value port ) {
	struct sockaddr_in addr;
	val_check_kind(o,k_socket);
	val_check(host,int32);
	val_check(port,int);
	memset(&addr,0,sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(val_int(port));
	*(int*)&addr.sin_addr.s_addr = val_int32(host);
	if( connect(val_sock(o),(struct sockaddr*)&addr,sizeof(addr)) != 0 )
		return block_error();
	return val_true;
}
Ejemplo n.º 9
0
/**
	socket_bind : 'socket -> host : 'int32 -> port:int -> void
	<doc>Bind the socket for server usage on the given host and port</doc>
**/
static value socket_bind( value o, value host, value port ) {
	int opt = 1;
	struct sockaddr_in addr;
	val_check_kind(o,k_socket);
	val_check(host,int32);
	val_check(port,int);
	memset(&addr,0,sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(val_int(port));
	*(int*)&addr.sin_addr.s_addr = val_int32(host);
	#ifndef NEKO_WINDOWS
	setsockopt(val_sock(o),SOL_SOCKET,SO_REUSEADDR,(char*)&opt,sizeof(opt));
	#endif
	if( bind(val_sock(o),(struct sockaddr*)&addr,sizeof(addr)) == SOCKET_ERROR )
		neko_error();
	return val_true;
}
Ejemplo n.º 10
0
/**
	host_reverse : 'int32 -> string
	<doc>Reverse the DNS of the given IP address.</doc>
**/
static value host_reverse( value host ) {
	struct hostent *h;
	unsigned int ip;
	val_check(host,int32);
	ip = val_int32(host);
#	if defined(NEKO_WINDOWS) || defined(NEKO_MAC)
	h = gethostbyaddr((char *)&ip,4,AF_INET);
#	else
	struct hostent htmp;
	int errcode;
	char buf[1024];
	gethostbyaddr_r((char *)&ip,4,AF_INET,&htmp,buf,1024,&h,&errcode);
#	endif
	if( h == NULL )
		neko_error();
	return alloc_string( h->h_name );
}
Ejemplo n.º 11
0
int api_val_int(value  arg1)
{
	return val_int32(arg1);
}
Ejemplo n.º 12
0
static void val_buffer_rec( buffer b, value v, vlist *stack ) {
	char buf[32];
	int i, l;
	vlist *vtmp = stack;
	while( vtmp != NULL ) {
		if( vtmp->v == v ) {
			buffer_append_sub(b,"...",3);
			return;
		}
		vtmp = vtmp->next;
	}
	switch( val_type(v) ) {
	case VAL_INT:
		buffer_append_sub(b,buf,sprintf(buf,"%d",val_int(v)));
		break;
	case VAL_STRING:
		buffer_append_sub(b,val_string(v),val_strlen(v));
		break;
	case VAL_FLOAT:
		buffer_append_sub(b,buf,sprintf(buf,FLOAT_FMT,val_float(v)));
		break;
	case VAL_NULL:
		buffer_append_sub(b,"null",4);
		break;
	case VAL_BOOL:
		if( val_bool(v) )
			buffer_append_sub(b,"true",4);
		else
			buffer_append_sub(b,"false",5);
		break;
	case VAL_FUNCTION:
		buffer_append_sub(b,buf,sprintf(buf,"#function:%d",val_fun_nargs(v)));
		break;
	case VAL_OBJECT:
		{
			value s = val_field(v,id_string);
			if( s != val_null )
				s = val_callEx(v,s,NULL,0,NULL);
			if( val_is_string(s) )
				buffer_append_sub(b,val_string(s),val_strlen(s));
			else {
				vlist2 vtmp;
				vtmp.v = v;
				vtmp.next = stack;
				vtmp.b = b;
				vtmp.prev = 0;
				buffer_append_sub(b,"{",1);
				val_iter_fields(v,val_buffer_fields,&vtmp);
				if( vtmp.prev )
					buffer_append_sub(b," }",2);
				else
					buffer_append_sub(b,"}",1);
			}
			break;
		}
	case VAL_ARRAY:
		buffer_append_sub(b,"[",1);
		l = val_array_size(v);
		{
			vlist vtmp;
			vtmp.v = v;
			vtmp.next = stack;
			for(i=0;i<l;i++) {
				value vi = val_array_ptr(v)[i];
				val_buffer_rec(b,vi,&vtmp);
				if( i != l - 1 )
					buffer_append_sub(b,",",1);
			}
		}
		buffer_append_sub(b,"]",1);
		break;
	case VAL_INT32:
		buffer_append_sub(b,buf,sprintf(buf,"%d",val_int32(v)));
		break;
	case VAL_ABSTRACT:
		buffer_append_sub(b,"#abstract",9);
		break;
	default:
		buffer_append_sub(b,"#unknown",8);
		break;
	}
}
Ejemplo n.º 13
0
static void hash_rec( value v, int *h, vlist *l ) {
	val_type t = val_type(v);
	switch( t ) {
	case VAL_INT:
		HBIG(val_int(v));
		break;
	case VAL_INT32:
		HBIG(val_int32(v));
		break;
	case VAL_NULL:
		HSMALL(0);
		break;
	case VAL_FLOAT:
		{ 
			int k = sizeof(tfloat);
			while( k )
				HSMALL(val_string(v)[--k]);
		}
		break;
	case VAL_BOOL:
		HSMALL(val_bool(v));
		break;
	case VAL_STRING:
		{
			int k = val_strlen(v);
			while( k )
				HSMALL(val_string(v)[--k]);
		}
		break;
	case VAL_OBJECT:
	case VAL_ARRAY:
		{
			vlist *tmp = l;
			int k = 0;
			while( tmp != NULL ) {
				if( tmp->v == v ) {
					HSMALL(k);
					return;
				}
				k = k + 1;
				tmp = tmp->next;
			}
		}
		if( t == VAL_OBJECT ) {
			vparam p;
			p.h = h;
			p.l.v = v;
			p.l.next = l;
			val_iter_fields(v,hash_obj_rec,&p);
			v = (value)((vobject*)v)->proto;
			if( v != NULL )
				hash_rec(v,h,&p.l);
		} else {
			vlist cur;
			int k = val_array_size(v);
			cur.v = v;
			cur.next = l;
			while( k )
				hash_rec(val_array_ptr(v)[--k],h,&cur);
		}
		break;
	default:
		// ignore since we want hashes to be stable wrt memory
		break;
	}
}
Ejemplo n.º 14
0
/**
	$not : any -> bool
	<doc>Return true if [v] is [false] or [null] or [0]</doc>
**/
static value builtin_not( value f ) {
	return alloc_bool(f == val_false || f == val_null || f == alloc_int(0) || (!val_is_int(f) && val_tag(f) == VAL_INT32 && val_int32(f) == 0));
}
Ejemplo n.º 15
0
/**
	$istrue : v:any -> bool
	<doc>Return true if [v] is not [false], not [null] and not 0</doc>
**/
static value builtin_istrue( value f ) {
	return alloc_bool(f != val_false && f != val_null && f != alloc_int(0) && (val_is_int(f) || val_tag(f) != VAL_INT32 || val_int32(f) != 0));
}
Ejemplo n.º 16
0
void serialize_rec( sbuffer *b, value o ) {
	b->nrec++;
	if( b->nrec > 350 )
		failure("Serialization stack overflow");
	switch( val_type(o) ) {
	case VAL_NULL:
		write_char(b,'N');
		break;
	case VAL_BOOL:
		if( val_bool(o) )
			write_char(b,'T');
		else
			write_char(b,'F');
		break;
	case VAL_INT:
		write_char(b,'i');
		write_int(b,val_int(o));
		break;
	case VAL_FLOAT:
		write_char(b,'f');
		write_str(b,sizeof(tfloat),&val_float(o));
		break;
	case VAL_STRING:
		if( !write_ref(b,o,NULL) ) {
			write_char(b,'s');
			write_int(b,val_strlen(o));
			write_str(b,val_strlen(o),val_string(o));
		}
		break;
	case VAL_OBJECT:
		{
			value s;
			if( !write_ref(b,o,&s) ) {
				if( s != NULL ) {
					// reference was not written
					if( !val_is_function(s) || (val_fun_nargs(s) != 0 && val_fun_nargs(s) != VAR_ARGS) )
						failure("Invalid __serialize method");
					write_char(b,'x');
					serialize_rec(b,((neko_module*)((vfunction*)s)->module)->name);
					serialize_rec(b,val_ocall0(o,id_serialize));
					// put reference back
					write_ref(b,o,NULL);
					break;
				}
				write_char(b,'o');
				val_iter_fields(o,serialize_fields_rec,b);
				write_int(b,0);
				o = (value)((vobject*)o)->proto;
				if( o == NULL )
					write_char(b,'z');
				else {
					write_char(b,'p');
					serialize_rec(b,o);
				}
			}
		}
		break;
	case VAL_ARRAY:
		if( !write_ref(b,o,NULL) ) {
			int i;
			int n = val_array_size(o);
			write_char(b,'a');
			write_int(b,n);
			for(i=0;i<n;i++)
				serialize_rec(b,val_array_ptr(o)[i]);
		}
		break;
	case VAL_FUNCTION:
		if( !write_ref(b,o,NULL) ) {
			neko_module *m;
			if( val_tag(o) == VAL_PRIMITIVE ) {
				// assume that alloc_array(0) return a constant array ptr
				// we don't want to access custom memory (maybe not a ptr)
				if( ((vfunction*)o)->env != alloc_array(0) )
					failure("Cannot Serialize Primitive with environment");
				write_char(b,'p');
				write_int(b,((vfunction*)o)->nargs);
				serialize_rec(b,((vfunction*)o)->module);
				break;
			}
			if( val_tag(o) == VAL_JITFUN )
				failure("Cannot Serialize JIT method");
			write_char(b,'L');
			m = (neko_module*)((vfunction*)o)->module;
			serialize_rec(b,m->name);
			write_int(b,(int)((int_val*)((vfunction*)o)->addr - m->code));
			write_int(b,((vfunction*)o)->nargs);
			serialize_rec(b,((vfunction*)o)->env);
		}
		break;
	case VAL_INT32:
		write_char(b,'I');
		write_int(b,val_int32(o));
		break;
	case VAL_ABSTRACT:
		if( val_is_kind(o,k_hash) ) {
			int i;
			vhash *h = val_hdata(o);
			write_char(b,'h');
			write_int(b,h->ncells);
			write_int(b,h->nitems);
			for(i=0;i<h->ncells;i++) {
				hcell *c = h->cells[i];
				while( c != NULL ) {
					write_int(b,c->hkey);
					serialize_rec(b,c->key);
					serialize_rec(b,c->val);
					c = c->next;
				}
			}
			break;
		}
	default:
		failure("Cannot Serialize Abstract");
		break;
	}
	b->nrec--;
}
Ejemplo n.º 17
0
/**
	host_to_string : 'int32 -> string
	<doc>Return a string representation of the IP address.</doc>
**/
static value host_to_string( value ip ) {
	struct in_addr i;
	val_check(ip,int32);
	*(int*)&i = val_int32(ip);
	return alloc_string( inet_ntoa(i) );
}