예제 #1
0
파일: misc.c 프로젝트: MattTuttle/neko
/**
	enable_jit : ?bool -> ?bool
	<doc>Enable or disable the JIT. Calling enable_jit(null) tells if JIT is enabled or not</doc>
**/
static value enable_jit( value b ) {
	if( val_is_null(b) )
		return alloc_bool(neko_vm_jit(neko_vm_current(),-1));
	val_check(b,bool);
	neko_vm_jit(neko_vm_current(),val_bool(b));
	return val_null;
}
예제 #2
0
static int boot_main(int argc, char *argv[] ) {
	neko_vm *vm;
	value args[2];
	value mload, exc = NULL;

	char* root = getSwitch(argc,argv,"swroot");
	char* rootFromBundle = root ? NULL : getSwitchFromBundle("swroot");

	char* index = getSwitch(argc,argv,"swindex");
	if(!index) index = getSwitchFromBundle("swindex");

#if OSX
	char* tmpRootBuffer = NULL;
	if (rootFromBundle) {
		if (stricmp("SW_BUNDLE_PARENT",rootFromBundle)==0) {
			// folder containing bundle is path:
			root = getBundleRoot();
			strcat(root,"/..");
		} else {
			// path is relative to bundle:
			root = tmpRootBuffer = malloc(FILENAME_MAX);
			sprintf(root,"%s/%s",getBundleRoot(),rootFromBundle);
		}
	}
#endif

	// if root folder is specified, change the current directory:
	if( root ) {
		chdir(root);
#		if OSX
 		if (tmpRootBuffer)
 			free(tmpRootBuffer);
#		endif
	}

	// printf("boot-loader computed working folder: %s\n",root);
	// printf("boot-loader set working folder: %s\n",getcwd(NULL));

	// initialize Neko Virtual Machine
	neko_global_init(&vm);
	vm = neko_vm_alloc(NULL);
	neko_vm_jit(vm,1);
	neko_vm_select(vm);
	mload = neko_default_loader(argv, argc);

	args[0] = alloc_string(index ? index : DEFAULT_INDEX);
	args[1] = mload;
	val_callEx(mload,val_field(mload,val_id("loadmodule")),args,2,&exc);
	if( exc != NULL )
		report(vm,exc);
	vm = NULL;
	neko_global_free();

	while(switches_count--) {
		free(switches[switches_count]);
	}
	if (switches) free(switches);

	return( exc != NULL );
}
예제 #3
0
파일: thread.c 프로젝트: ConstNW/neko
static void thread_init( void *_p ) {
	tparams *p = (tparams*)_p;
	neko_vm *vm;
	// init the VM and set current thread
	vm = neko_vm_alloc(NULL);
	p->t = alloc_thread(vm);
	neko_vm_jit(vm,p->jit);
	neko_vm_select(vm);
	neko_vm_set_custom(vm,k_thread,p->t);
}
예제 #4
0
파일: thread.c 프로젝트: ConstNW/neko
/**
	thread_create : f:function:1 -> p:any -> 'thread
	<doc>Creates a thread that will be running the function [f(p)]</doc>
**/
static value thread_create( value f, value param ) {
	tparams *p;
	val_check_function(f,1);
	p = (tparams*)alloc(sizeof(tparams));
	p->callb = f;
	p->callparam = param;
	p->jit = neko_vm_jit(neko_vm_current(),-1);	
	if( !neko_thread_create(thread_init,thread_loop,p,&p->handle) )
		neko_error();
	return p->t->v;
}
예제 #5
0
static void preload_module( const char *name, server_rec *serv ) {
	value exc = NULL;
	neko_vm *vm = neko_vm_alloc(NULL);
	value mload = neko_default_loader(NULL,0);
	value m, read_path, exec;
	time_t time = 0;
	neko_vm_select(vm);
	if( config.use_jit ) neko_vm_jit(vm,1);
	if( !exc ) {
		value args[] = { alloc_string("std@module_read_path"), alloc_int(3) };
		read_path = val_callEx(mload,val_field(mload,val_id("loadprim")),args,2,&exc);
	}
	if( !exc ) {
		value args[] = { alloc_string("std@module_exec"), alloc_int(1) };
		exec = val_callEx(mload,val_field(mload,val_id("loadprim")),args,2,&exc);
	}
	if( !exc ) {
		value args[] = { val_null, alloc_string(name), mload };
		char *p = strrchr(val_string(args[1]),'.');
		if( p != NULL ) *p = 0;
		m = val_callEx(mload,read_path,args,3,&exc);
	}
	if( !exc ) {
		struct stat t;
		if( stat(name,&t) )
			exc = alloc_string("failed to stat()");
		else
			time = t.st_mtime;
	}
	if( !exc ) {
		value f = alloc_function(init_module,0,"init_module");
		value env = alloc_array(2);
		val_array_ptr(env)[0] = exec;
		val_array_ptr(env)[1] = m;
		((vfunction*)f)->env = env;
		cache_module(name,time,f);
	}
	if( exc ) {
		buffer b = alloc_buffer(NULL);
		val_buffer(b,exc);
		ap_log_error(APLOG_MARK,APLOG_WARNING,LOG_SUCCESS serv,"Failed to preload module '%s' : %s",name,val_string(buffer_to_string(b)));
	}
	neko_vm_select(NULL);
}
예제 #6
0
int neko_has_embedded_module( neko_vm *vm ) {
	char *exe = executable_path();
	unsigned char id[8];
	int pos;
	if( exe == NULL )
		return 0;
	self = fopen(exe,"rb");
	if( self == NULL )
		return 0;
	fseek(self,-8,SEEK_END);
	if( fread(id,1,8,self) != 8 || id[0] != 'N' || id[1] != 'E' || id[2] != 'K' || id[3] != 'O' ) {
		fclose(self);
		return 0;
	}
	pos = id[4] | id[5] << 8 | id[6] << 16;
	fseek(self,pos,SEEK_SET);
	// flags
	if( (id[7] & 1) == 0 )
		neko_vm_jit(vm,1);
	return 1;
}
예제 #7
0
파일: main.c 프로젝트: MattTuttle/neko
int neko_has_embedded_module( neko_vm *vm ) {
	char *exe = executable_path();
	unsigned char id[8];
	int beg=-1, end=0;
	if( exe == NULL )
		return 0;

#ifdef SEPARATE_SECTION_FOR_BYTECODE
	/* Look for a ,nekobytecode section in the executable... */
	if ( val_true != elf_find_embedded_bytecode(exe,&beg,&end) ) {
		/* Couldn't find a .nekobytecode section,
		   fallback to looking at the end of the executable... */
		beg = -1; end = 0;
	}
#endif
	/* Back up eight bytes to the possible bytecode signature... */
	end -= 8;

	self = fopen(exe,"rb");
	if( self == NULL )
		return 0;

	fseek(self,end,(end<0)?SEEK_END:SEEK_SET);
	if( fread(id,1,8,self) != 8 || id[0] != 'N' || id[1] != 'E' || id[2] != 'K' || id[3] != 'O' ) {
		fclose(self);
		return 0;
	}

        if ( -1 == beg ) {
		beg = id[4] | id[5] << 8 | id[6] << 16;
	}
	fseek(self,beg,(beg<0)?SEEK_END:SEEK_SET);
	// flags
	if( (id[7] & 1) == 0 )
		neko_vm_jit(vm,1);
	return 1;
}
예제 #8
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;
}
예제 #9
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;
}