Пример #1
0
// Array access - generic
int api_val_array_size(value  arg1)
{
	if (val_is_array(arg1))
	   return val_array_size(arg1);
	value l = val_field(arg1,length_id);
	return val_int(l);
}
Пример #2
0
Файл: main.c Проект: robinp/neko
static void report( neko_vm *vm, value exc, int isexc ) {
	int i;
	buffer b = alloc_buffer(NULL);
	value st = neko_exc_stack(vm);
	for(i=0;i<val_array_size(st);i++) {
		value s = val_array_ptr(st)[i];
		buffer_append(b,"Called from ");
		if( val_is_null(s) )
			buffer_append(b,"a C function");
		else if( val_is_string(s) ) {
			buffer_append(b,val_string(s));
			buffer_append(b," (no debug available)");
		} else if( val_is_array(s) && val_array_size(s) == 2 && val_is_string(val_array_ptr(s)[0]) && val_is_int(val_array_ptr(s)[1]) ) {
			val_buffer(b,val_array_ptr(s)[0]);
			buffer_append(b," line ");
			val_buffer(b,val_array_ptr(s)[1]);
		} else
			val_buffer(b,s);
		buffer_append_char(b,'\n');
	}
	if( isexc )
		buffer_append(b,"Uncaught exception - ");
	val_buffer(b,exc);
#	ifdef NEKO_STANDALONE
	neko_standalone_error(val_string(buffer_to_string(b)));
#	else
	fprintf(stderr,"%s\n",val_string(buffer_to_string(b)));
#	endif
}
Пример #3
0
EXTERN value neko_select_file( value path, const char *file, const char *ext ) {
	struct stat s;
	value ff;
	buffer b = alloc_buffer(file);
	buffer_append(b,ext);
	ff = buffer_to_string(b);
	if( stat(val_string(ff),&s) == 0 ) {
		char *p = strchr(file,'/');
		if( p == NULL )
			p = strchr(file,'\\');
		if( p != NULL )
			return ff;
		b = alloc_buffer("./");
		buffer_append(b,file);
		buffer_append(b,ext);
		return buffer_to_string(b);
	}
	while( val_is_array(path) && val_array_size(path) == 2 ) {
		value p = val_array_ptr(path)[0];
		buffer b = alloc_buffer(NULL);
		path = val_array_ptr(path)[1];
		val_buffer(b,p);
		val_buffer(b,ff);
		p = buffer_to_string(b);
		if( stat(val_string(p),&s) == 0 )
			return p;
	}
	return ff;
}
Пример #4
0
static void report( neko_vm *vm, value exc ) {
#if OSX
	CFStringRef title = CFSTR("Uncaught exception");
	CFStringRef message;
#endif
	int i = 0;
	buffer b = alloc_buffer(NULL);
	value st = neko_exc_stack(vm);
	if( val_array_size(st) > 20 ) {
		i = val_array_size(st) - 20;
		buffer_append(b,"...\n");
	}
	for(i;i<val_array_size(st);i++) {
		value s = val_array_ptr(st)[i];
		if( val_is_null(s) )
			buffer_append(b,"Called from a C function\n");
		else if( val_is_string(s) ) {
			buffer_append(b,"Called from ");
			buffer_append(b,val_string(s));
			buffer_append(b," (no debug available)\n");
		} else if( val_is_array(s) && val_array_size(s) == 2 && val_is_string(val_array_ptr(s)[0]) && val_is_int(val_array_ptr(s)[1]) ) {
			buffer_append(b,"Called from ");
			buffer_append(b,val_string(val_array_ptr(s)[0]));
			buffer_append(b," line ");
			val_buffer(b,val_array_ptr(s)[1]);
			buffer_append(b,"\n");
		} else {
			buffer_append(b,"Called from ");
			val_buffer(b,s);
			buffer_append(b,"\n");
		}
	}
	val_buffer(b,exc);
#if _WIN32
	MessageBox(NULL,val_string(buffer_to_string(b)),"Uncaught exception",MB_OK | MB_ICONERROR);
#elif OSX
	message = CFStringCreateWithCString(NULL,val_string(buffer_to_string(b)), kCFStringEncodingUTF8);
	CFUserNotificationDisplayNotice(0,0,NULL,NULL,NULL,title,message,NULL);
#elif LINUX
	fprintf(stderr,"Uncaught Exception: %s\n",val_string(buffer_to_string(b)));
#endif
}
Пример #5
0
static fd_set *make_socket_array( value a, fd_set *tmp, SOCKET *n ) {
	int i, len;
	SOCKET sock;
	FD_ZERO(tmp);
	if( val_is_null(a) )
		return tmp;
	if( !val_is_array(a) )
		return &INVALID;
	len = val_array_size(a);
	if( len > FD_SETSIZE )
		val_throw(alloc_string("Too many sockets in select"));
	for(i=0;i<len;i++) {
		value s = val_array_i(a,i);
                // make sure it is a socket...
		sock = val_sock(s);
		if( sock > *n )
			*n = sock;
		FD_SET(sock,tmp);
	}
	return tmp;
}
Пример #6
0
static fd_set *make_socket_array( value a, int len, fd_set *tmp, SOCKET *n ) {
	int i;
	SOCKET sock;
	if( val_is_null(a) )
		return NULL;
	if( !val_is_array(a) )
		return &INVALID;
	if( len > FD_SETSIZE )
		val_throw(alloc_string("Too many sockets in select"));
	FD_ZERO(tmp);
	for(i=0;i<len;i++) {
		value s = val_array_ptr(a)[i];
		if( !val_is_kind(s,k_socket) )
			return &INVALID;
		sock = val_sock(s);
		if( sock > *n )
			*n = sock;
		FD_SET(sock,tmp);
	}
	return tmp;
}
Пример #7
0
// Determine value type
int api_val_type(value  arg1)
{
	int t=val_type(arg1);
	if (t==VAL_OBJECT)
	{
		value __a = val_field(arg1,__a_id);
		if (val_is_array(__a))
			return valtArray;
		value __s = val_field(arg1,__s_id);
		if (val_is_string(__s))
			return valtString;
	}
	if (t<7)
		return (ValueType)t;
	if (t==VAL_ABSTRACT)
		return valtAbstractBase;

	if (t==VAL_PRIMITIVE || t==VAL_JITFUN)
		return valtFunction;
	if (t==VAL_32_BITS || t==VAL_INT)
		return valtInt;
	return valtNull;
}
Пример #8
0
void NekoCodeChunk::neko_dump(std::string const & indent) const {
	for (const_iterator it = begin();
		 it != end();
		 ++it)
		{
			std::cout << indent << it->first << ": ";
			print_neko_instruction((OPCODE) it->second.first, it->second.second, parameter_table[it->second.first]);

			std::cout << "; // ";
			{
				int ppc = (int)((int_val *)it->first - m->code);
				int idx = m->dbgidxs[ppc>>5].base + bitcount(m->dbgidxs[ppc>>5].bits >> (31 - (ppc & 31)));
				value s = val_array_ptr(m->dbgtbl)[idx];
				if( val_is_string(s) )
					printf("%s",val_string(s));
				else if( val_is_array(s) && val_array_size(s) == 2 && val_is_string(val_array_ptr(s)[0]) && val_is_int(val_array_ptr(s)[1]) )
					printf("file %s line %d",val_string(val_array_ptr(s)[0]),val_int(val_array_ptr(s)[1]));
				else
					printf("???");
			}
			std::cout << std::endl;
		}
}
Пример #9
0
static value unserialize_rec( sbuffer *b, value loader ) {
	switch( read_char(b) ) {
	case 'N':
		return val_null;
	case 'T':
		return val_true;
	case 'F':
		return val_false;
	case 'i':
		return alloc_int(read_int(b));
	case 'I':
		return alloc_int32(read_int(b));
	case 'f':
		{
			tfloat d;
			read_str(b,sizeof(tfloat),&d);
			return alloc_float(d);
		}
	case 's':
		{
			int l = read_int(b);
			value v;
			if( l < 0 || l > max_string_size )
				ERROR();
			v = alloc_empty_string(l);
			add_ref(b,v);
			read_str(b,l,(char*)val_string(v));
			return v;
		}
	case 'o':
		{
			int f;
			value o = alloc_object(NULL);
			add_ref(b,o);
			while( (f = read_int(b)) != 0 ) {
				value fval = unserialize_rec(b,loader);
				alloc_field(o,(field)f,fval);
			}
			switch( read_char(b) ) {
			case 'p':
				{
					value v = unserialize_rec(b,loader);
					if( !val_is_object(v) )
						ERROR();
					((vobject*)o)->proto = (vobject*)v;
				}
				break;
			case 'z':
				break;
			default:
				ERROR();
			}
			return o;
		}
	case 'r':
		{
			int n = read_int(b);
			if( n < 0 || n >= b->nrefs )
				ERROR();
			return b->trefs[b->nrefs - n - 1];
		}
	case 'a':
		{
			int i;
			int n = read_int(b);
			value o;
			value *t;
			if( n < 0 || n > max_array_size )
				ERROR();
			o = alloc_array(n);
			t = val_array_ptr(o);
			add_ref(b,o);
			for(i=0;i<n;i++)
				t[i] = unserialize_rec(b,loader);
			return o;

		}
	case 'p':
		{
			int nargs = read_int(b);
			vfunction *f = (vfunction*)alloc_function((void*)1,nargs,NULL);
			vfunction *f2;
			value name;
			add_ref(b,(value)f);
			name = unserialize_rec(b,loader);
			f2 = (vfunction*)val_ocall2(loader,id_loadprim,name,alloc_int(nargs));
			if( !val_is_function(f2) || val_fun_nargs(f2) != nargs )
				failure("Loader returned not-a-function");
			f->t = f2->t;
			f->addr = f2->addr;
			f->module = f2->module;
			return (value)f;
		}
	case 'L':
		{
			vfunction *f = (vfunction*)alloc_function((void*)1,0,NULL);
			value mname;
			int pos;
			int nargs;
			value env;
			add_ref(b,(value)f);
			mname = unserialize_rec(b,loader);
			pos = read_int(b);
			nargs = read_int(b);
			env = unserialize_rec(b,loader);
			if( !val_is_array(env) )
				ERROR();
			{
				value exp = val_ocall2(loader,id_loadmodule,mname,loader);
				value mval;
				unsigned int i;
				int_val *mpos;
				neko_module *m;
				if( !val_is_object(exp) ) {
					buffer b = alloc_buffer("module ");
					val_buffer(b,mname);
					buffer_append(b," is not an object");
					bfailure(b);
				}
				mval = val_field(exp,id_module);
				if( !val_is_kind(mval,neko_kind_module) ) {
					buffer b = alloc_buffer("module ");
					val_buffer(b,mname);
					buffer_append(b," has invalid type");
					bfailure(b);
				}
				m = (neko_module*)val_data(mval);
				mpos = m->code + pos;
				for(i=0;i<m->nglobals;i++) {
					vfunction *g = (vfunction*)m->globals[i];
					if( val_is_function(g) && g->addr == mpos && g->module == m && g->nargs == nargs ) {
						f->t = VAL_FUNCTION;
						f->env = env;
						f->addr = mpos;
						f->nargs = nargs;
						f->module = m;
						return (value)f;
					}
				}
				{
					buffer b = alloc_buffer("module ");
					val_buffer(b,mname);
					buffer_append(b," has been modified");
					bfailure(b);
				}
			}
			return val_null;
		}
	case 'x':
		{
			value mname = unserialize_rec(b,loader);
			value data = unserialize_rec(b,loader);
			value exports = val_ocall2(loader,id_loadmodule,mname,loader);
			value s;
			if( !val_is_object(exports) ) {
				buffer b = alloc_buffer("module ");
				val_buffer(b,mname);
				buffer_append(b," is not an object");
				bfailure(b);
			}
			s = val_field(exports,id_unserialize);
			if( !val_is_function(s) || (val_fun_nargs(s) != 1 && val_fun_nargs(s) != VAR_ARGS) ) {
				buffer b = alloc_buffer("module ");
				val_buffer(b,mname);
				buffer_append(b," has invalid __unserialize function");
			}
			s = val_call1(s,data);
			add_ref(b,s);
			return s;
		}
	case 'h':
		{
			int i;
			vhash *h = (vhash*)alloc(sizeof(vhash));
			h->ncells = read_int(b);
			h->nitems = read_int(b);
			h->cells = (hcell**)alloc(sizeof(hcell*)*h->ncells);
			for(i=0;i<h->ncells;i++)
				h->cells[i] = NULL;
			for(i=0;i<h->nitems;i++) {
				hcell **p;
				hcell *c = (hcell*)alloc(sizeof(hcell));
				c->hkey = read_int(b);
				c->key = unserialize_rec(b,loader);
				c->val = unserialize_rec(b,loader);
				c->next = NULL;
				p = &h->cells[c->hkey % h->ncells];
				while( *p != NULL )
					p = &(*p)->next;
				*p = c;
			}
			return alloc_abstract(k_hash,h);
		}
	default:
		ERROR();
		return val_null;
	}
}
Пример #10
0
/**
	sprintf : fmt:string -> params:(any | array) -> string
	<doc>
	Format a string. If only one parameter is needed then it can be
	directly passed, either the parameters need to be stored in an array.
	The following formats are accepted (with corresponding types) :
	<ul>
		<li>[%s] : string</li>
		<li>[%d] [%x] [%X] : int</li>
		<li>[%c] : int in the 0..255 range</li>
		<li>[%b] : bool</li>
		<li>[%f] : float</li>
	</ul>
	</doc>
**/
static value neko_sprintf( value fmt, value params ) {
	const char *last, *cur, *end;
	int count = 0;
	buffer b;
	val_check(fmt,string);
	b = alloc_buffer(0);
	last = val_string(fmt);
	cur = last;
	end = cur + val_strlen(fmt);
	while( cur != end ) {
		if( *cur == '%' ) {
			int width = 0, prec = 0, flags = 0;
			buffer_append_sub(b,last,cur - last);
			cur++;
			while( *cur >= '0' && *cur <= '9' ) {
				width = width * 10 + (*cur - '0');
				cur++;
			}
			if( *cur == '.' ) {
				cur++;
				while( *cur >= '0' && *cur <= '9' ) {
					prec = prec * 10 + (*cur - '0');
					cur++;
				}
			}
			if( *cur == '%' ) {
				buffer_append_sub(b,"%",1);
				cur++;
			} else {
				value param;
				if( count == 0 && !val_is_array(params) ) { // first ?
					param = params;
					count++;
				} else if( !val_is_array(params) || val_array_size(params) <= count )
					return alloc_null();
				else
					param = val_array_i(params,count++);
				switch( *cur ) {
				case 'c':
					{
						int c;
						char cc;
						val_check(param,int);
						c = val_int(param);
						if( c < 0 || c > 255 )
							return alloc_null();
						cc = (char)c;
						buffer_append_sub(b,&cc,1);
					}
					break;
				case 'x':
					flags |= HEX_SMALL;
				case 'X':
					flags |= HEX;
				case 'd':
					{
						char tmp[10];
						int sign = 0;
						int size = 0;
						int tsize;
						int n;
						val_check(param,int);
						n = val_int(param);
						if( !(flags & HEX) && n < 0 ) {
							sign++;
							prec--;
							n = -n;
						} else if( n == 0 )
							tmp[9-size++] = '0';
						if( flags & HEX ) {
							unsigned int nn = (unsigned int)n;
							while( nn > 0 ) {
								int k = nn&15;
								if( k < 10 )
									tmp[9-size++] = k + '0';
								else
									tmp[9-size++] = (k - 10) + ((flags & HEX_SMALL)?'a':'A');
								nn = nn >> 4;
							}
						} else {
							while( n > 0 ) {
								tmp[9-size++] = (n % 10) + '0';
								n = n / 10;
							}
						}
						tsize = (size > prec)?size:prec + sign;
						while( width > tsize ) {
							width--;
							buffer_append_sub(b," ",1);
						}
						if( sign )
							buffer_append_sub(b,"-",1);
						while( prec > size ) {
							prec--;
							buffer_append_sub(b,"0",1);
						}
						buffer_append_sub(b,tmp+10-size,size);
					}
					break;
				case 'f':
					{
						val_check(param,float);
						val_buffer(b,param);
					}
					break;
				case 's':
					{
						int size;
						int tsize;
						val_check(param,string);
						size = val_strlen(param);
						tsize = (size > prec)?size:prec;
						while( width > tsize ) {
							width--;
							buffer_append_sub(b," ",1);
						}
						while( prec > size ) {
							prec--;
							buffer_append_sub(b," ",1);
						}
						buffer_append_sub(b,val_string(param),size);
					}
					break;
				case 'b':
					{
						val_check(param,bool);
						buffer_append_sub(b,val_bool(param)?"true":"false",val_bool(param)?4:5);
					}
					break;
				default:
					return alloc_null();
					break;
				}
			}
Пример #11
0
static int neko_handler_rec( request_rec *r ) {
	mcontext ctx;
	neko_vm *vm;
	const char *ctype;
	value exc = NULL;

/*
	Seems to crash on Windows. And on Linux, we rarely have libGC 7.x installed anyway

#	if defined(APACHE_2_X) || defined(NEKO_WINDOWS)
	// we are using threads, so let's make sure that the current thread is registered
	neko_thread_register(true);
#	endif
*/

	config.hits++;

	ctx.r = r;
	ctx.main = cache_find(r);
	ctx.post_data = val_null;
	ctx.headers_sent = false;
	ctx.content_type = alloc_string("text/html");
    r->content_type = val_string(ctx.content_type);

	if( ap_setup_client_block(r,REQUEST_CHUNKED_ERROR) != 0 ) {
		send_headers(&ctx);
		apache_error(APLOG_WARNING,r,"ap_setup_client_block failed");
		return OK;
	}

	ctype = ap_table_get(r->headers_in,"Content-Type");
	if( (!ctype || strstr(ctype,"multipart/form-data") == NULL) && ap_should_client_block(r) ) {
#		define MAXLEN 1024
		char buf[MAXLEN];
		int len;
		int tlen = 0;
		buffer b = alloc_buffer(NULL);
		while( (len = ap_get_client_block(r,buf,MAXLEN)) > 0 ) {
			if( tlen < config.max_post_size )
				buffer_append_sub(b,buf,len);
			tlen += len;
		}
		if( tlen >= config.max_post_size ) {
			send_headers(&ctx);
			apache_error(APLOG_WARNING,r,"Maximum POST data exceeded. Try using multipart encoding");
			return OK;
		}
		ctx.post_data = buffer_to_string(b);
	}

	vm = neko_vm_alloc(NULL);
	if( config.use_stats ) neko_vm_set_stats(vm,neko_stats_measure,config.use_prim_stats?neko_stats_measure:NULL);

	neko_vm_set_custom(vm,k_mod_neko,&ctx);
	if( config.use_jit && !neko_vm_jit(vm,1) ) {
		send_headers(&ctx);
		apache_error(APLOG_WARNING,r,"JIT required by env. var but not enabled in NekoVM");
		return OK;
	}

	neko_vm_redirect(vm,request_print,&ctx);
	neko_vm_select(vm);

	if( ctx.main != NULL ) {
		value old = ctx.main;
		if( config.use_stats ) neko_stats_measure(vm,r->filename,1);
		val_callEx(val_null,old,NULL,0,&exc);
		if( config.use_stats ) neko_stats_measure(vm,r->filename,0);
		if( old != ctx.main ) cache_module(r->filename,FTIME(r),ctx.main);
	} else {
		char *base_uri = request_base_uri(r);
		value mload = neko_default_loader(&base_uri,1);
		value args[] = { alloc_string(r->filename), mload };
		char *p = strrchr(val_string(args[0]),'.');
		if( p != NULL )
			*p = 0;
		val_callEx(mload,val_field(mload,val_id("loadmodule")),args,2,&exc);
		if( ctx.main != NULL && config.use_cache )
			cache_module(r->filename,FTIME(r),ctx.main);
	}

	if( exc != NULL ) {
		buffer b = alloc_buffer(NULL);
		value v;
		int i;
		const char *p, *start;
		value st = neko_exc_stack(vm);
		val_buffer(b,exc);
		config.exceptions++;
		ap_soft_timeout("Client Timeout",r);
		send_headers(&ctx);
		v = buffer_to_string(b);
		p = val_string(v);
		start = p;
		ap_rprintf(r,"Uncaught exception - ");
		while( *p ) {
			if( *p == '<' || *p == '>' ) {
				ap_rwrite(start,(int)(p - start),r);
				ap_rwrite((*p == '<')?"&lt;":"&gt;",4, r);
				start = p + 1;
			}
			p++;
		}
		ap_rwrite(start,(int)(p - start),r);
		ap_rprintf(r,"<br/><br/>");
		for(i=0;i<val_array_size(st);i++) {
			value s = val_array_ptr(st)[i];
			if( val_is_null(s) )
				ap_rprintf(r,"Called from a C function<br/>");
			else if( val_is_string(s) ) {
				ap_rprintf(r,"Called from %s (no debug available)<br/>",val_string(s));
			} else if( val_is_array(s) && val_array_size(s) == 2 && val_is_string(val_array_ptr(s)[0]) && val_is_int(val_array_ptr(s)[1]) )
				ap_rprintf(r,"Called from %s line %d<br/>",val_string(val_array_ptr(s)[0]),val_int(val_array_ptr(s)[1]));
			else {
				b = alloc_buffer(NULL);
				val_buffer(b,s);
				ap_rprintf(r,"Called from %s<br/>",val_string(buffer_to_string(b)));
			}
		}
		ap_kill_timeout(r);
		return OK;
	}

	send_headers(&ctx);
    return OK;
}
Пример #12
0
value * api_val_array_value(value  arg1)
{
	if (val_is_array(arg1))
	   return val_array_ptr(arg1);
	return val_array_ptr(val_field(arg1,__a_id));
}
Пример #13
0
void api_val_array_set_i(value  arg1,int arg2,value inVal)
{
	if (!val_is_array(arg1))
		arg1 = val_field(arg1,__a_id);
	val_array_ptr(arg1)[arg2] = inVal;
}
Пример #14
0
value  api_val_array_i(value  arg1,int arg2)
{
	if (val_is_array(arg1))
	   return val_array_ptr(arg1)[arg2];
	return val_array_ptr(val_field(arg1,__a_id))[arg2];
}