예제 #1
0
static int neko_handler( request_rec *r ) {
	int ret;
	if( strcmp(r->handler,"neko-handler") != 0)
		return DECLINED;
	if( config.use_stats ) neko_stats_measure(NULL,r->hostname,1);
	ret = neko_handler_rec(r);
	neko_vm_select(NULL);
	if( config.use_stats ) neko_stats_measure(NULL,r->hostname,0);
	gc_major();
	return ret;
}
예제 #2
0
파일: main.c 프로젝트: robinp/neko
int main( int argc, char *argv[] ) {
	neko_vm *vm;
	value mload;
	int r;
	_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
	neko_global_init();
	vm = neko_vm_alloc(NULL);
	neko_vm_select(vm);
#	ifdef NEKO_STANDALONE
	neko_standalone_init();
#	endif
	if( !neko_has_embedded_module(vm) ) {
		int jit = 1;
		int stats = 0;
		while( argc > 1 ) {
			if( strcmp(argv[1],"-interp") == 0 ) {
				argc--;
				argv++;
				jit = 0;
				continue;
			}
			if( strcmp(argv[1],"-stats") == 0 ) {
				argc--;
				argv++;
				stats = 1;
				neko_vm_set_stats(vm,neko_stats_measure,neko_stats_measure);
				neko_stats_measure(vm,"total",1);
				continue;
			}
			break;
		}
#		ifdef NEKO_POSIX
		if( jit ) {
			struct sigaction act;
			act.sa_sigaction = NULL;
			act.sa_handler = handle_signal;
			act.sa_flags = 0;
			sigemptyset(&act.sa_mask);
			sigaction(SIGSEGV,&act,NULL);
		}
#		endif
		neko_vm_jit(vm,jit);
		if( argc == 1 ) {
#			ifdef NEKO_STANDALONE
			report(vm,alloc_string("No embedded module in this executable"),0);
#			else
			printf("NekoVM %d.%d.%d (c)2005-2009 Motion-Twin\n  Usage : neko <file>\n",NEKO_VERSION/100,(NEKO_VERSION/10)%10,NEKO_VERSION%10);
#			endif
			mload = NULL;
			r = 1;
		} else {
			mload = default_loader(argv+2,argc-2);
			r = execute_file(vm,argv[1],mload);
		}
		if( stats ) {
			value v;
			neko_stats_measure(vm,"total",0);
			v = neko_stats_build(vm);
			val_print(alloc_string("TOT\tTIME\tCOUNT\tNAME\n"));
			while( v != val_null ) {
				char buf[256];
				value *s = val_array_ptr(v);
				int errors = val_int(s[4]);
				sprintf(buf,"%d\t%d\t%d\t%s%c",
					val_int(s[1]),
					val_int(s[2]),
					val_int(s[3]),
					val_string(s[0]),
					errors?' ':'\n');
				if( errors )
					sprintf(buf+strlen(buf),"ERRORS=%d\n",errors);
				val_print(alloc_string(buf));
				v = s[5];
			}
		}
	} else {
		mload = default_loader(argv+1,argc-1);
		r = neko_execute_self(vm,mload);
	}
	if( mload != NULL && val_field(mload,val_id("dump_prof")) != val_null )
		val_ocall0(mload,val_id("dump_prof"));
	vm = NULL;
	mload = NULL;
	neko_vm_select(NULL);
	neko_global_free();
	return r;
}
예제 #3
0
static void gc_major() {
	if( config.gc_period <= 0 || config.hits % config.gc_period != 0 ) return;
	if( config.use_stats ) neko_stats_measure(NULL,"gc",1);
	neko_gc_major();
	if( config.use_stats ) neko_stats_measure(NULL,"gc",0);
}
예제 #4
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;
}