Example #1
0
/**
	$varargs : f:function:1 -> function
	<doc>
	Return a variable argument function that, when called, will callback
	[f] with the array of arguments.
	</doc>
**/
static value builtin_varargs( value f ) {
	value fvar;
	val_check_function(f,1);
	fvar = alloc_function(varargs_callback,VAR_ARGS,"varargs");
	((vfunction*)fvar)->env = f;
	return fvar;
}
Example #2
0
File: main.c Project: robinp/neko
int neko_execute_self( neko_vm *vm, value mload ) {
	value args[] = { alloc_string("std@module_read"), alloc_int(2) };
	value args2[] = { alloc_string("std@module_exec"), alloc_int(1) };
	value args3[] = { alloc_function(read_bytecode,3,"boot_read_bytecode"), mload };
	value exc = NULL;
	value module_read, module_exec, module_val;
	module_read = val_callEx(mload,val_field(mload,val_id("loadprim")),args,2,&exc);
	if( exc != NULL ) {
		report(vm,exc,1);
		return 1;
	}
	module_exec = val_callEx(mload,val_field(mload,val_id("loadprim")),args2,2,&exc);
	if( exc != NULL ) {
		report(vm,exc,1);
		return 1;
	}
	module_val = val_callEx(val_null,module_read,args3,2,&exc);
	fclose(self);
	if( exc != NULL ) {
		report(vm,exc,1);
		return 1;
	}
	alloc_field(val_field(mload,val_id("cache")),val_id("_self"),module_val);
	val_callEx(val_null,module_exec,&module_val,1,&exc);
	if( exc != NULL ) {
		report(vm,exc,1);
		return 1;
	}
	return 0;
}
Example #3
0
static value loader_loadprim( value prim, value nargs ) {
	value o = val_this();
	value libs;
	val_check(o,object);
	val_check(prim,string);
	val_check(nargs,int);
	libs = val_field(o,id_loader_libs);
	val_check_kind(libs,k_loader_libs);
	if( val_int(nargs) >= 10 || val_int(nargs) < -1 )
		neko_error();
	{
		neko_vm *vm = NEKO_VM();
		void *ptr = load_primitive(val_string(prim),val_int(nargs),val_field(o,id_path),(liblist**)(void*)&val_data(libs));
		vfunction *f;
		if( ptr == NULL ) {
			buffer b = alloc_buffer("Primitive not found : ");
			val_buffer(b,prim);
			buffer_append(b,"(");
			val_buffer(b,nargs);
			buffer_append(b,")");
			bfailure(b);
		}
		f = (vfunction*)alloc_function(ptr,val_int(nargs),val_string(copy_string(val_string(prim),val_strlen(prim))));
		if( vm->pstats && val_int(nargs) <= 6 ) {
			value env = alloc_array(2);
			val_array_ptr(env)[0] = f->module;
			val_array_ptr(env)[1] = (value)(((int_val)f->addr) | 1);
			f->addr = stats_proxy;
			f->env = env;
		}
		return (value)f;
	}
}
Example #4
0
EXTERN value neko_default_loader( char **argv, int argc ) {
	value o = alloc_object(NULL);
	value args = alloc_array(argc);
	int i;
	for(i=0;i<argc;i++)
		val_array_ptr(args)[i] = alloc_string(argv[i]);
	alloc_field(o,id_path,init_path(getenv("NEKOPATH")));
	alloc_field(o,id_cache,alloc_object(NULL));
	alloc_field(o,id_loader_libs,alloc_abstract(k_loader_libs,NULL));
	alloc_field(o,val_id("args"),args);
	alloc_field(o,val_id("loadprim"),alloc_function(loader_loadprim,2,"loadprim"));
	alloc_field(o,val_id("loadmodule"),alloc_function(loader_loadmodule,2,"loadmodule"));
#ifdef NEKO_PROF
	alloc_field(o,val_id("dump_prof"),alloc_function(dump_prof,0,"dump_prof"));
#endif
	return o;
}
Example #5
0
/**
	$closure : function -> object -> any* -> function
	<doc>Build a closure by applying a given number of arguments to a function</doc>
**/
static value builtin_closure( value *args, int nargs ) {
	value f;
	value env;
	int fargs;
	if( nargs <= 1 )
		failure("Invalid closure arguments number");
	f = args[0];
	if( !val_is_function(f) )
		neko_error();
	fargs = val_fun_nargs(f);
	if( fargs != VAR_ARGS && fargs < nargs-2 )
		failure("Invalid closure arguments number");
	env = alloc_array(nargs);
	memcpy(val_array_ptr(env),args,nargs * sizeof(f));
	f = alloc_function( closure_callback, VAR_ARGS, "closure_callback" );
	((vfunction*)f)->env = env;
	return f;
}
Example #6
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);
}
Example #7
0
void neko_init_builtins() {
	neko_builtins = alloc_root(2);
	neko_builtins[0] = alloc_object(NULL);
	neko_builtins[1] = alloc_function(builtin_print,VAR_ARGS,"$print");

	BUILTIN(print,VAR_ARGS);

	BUILTIN(array,VAR_ARGS);
	BUILTIN(amake,1);
	BUILTIN(acopy,1);
	BUILTIN(asize,1);
	BUILTIN(asub,3);
	BUILTIN(ablit,5);
	BUILTIN(aconcat,1);

	BUILTIN(smake,1);
	BUILTIN(ssize,1);
	BUILTIN(scopy,1);
	BUILTIN(ssub,3);
	BUILTIN(sget,2);
	BUILTIN(sset,3);
	BUILTIN(sblit,5);
	BUILTIN(sfind,3);

	BUILTIN(new,1);
	BUILTIN(objget,2);
	BUILTIN(objset,3);
	BUILTIN(objcall,3);
	BUILTIN(objfield,2);
	BUILTIN(objremove,2);
	BUILTIN(objfields,1);
	BUILTIN(hash,1);
	BUILTIN(fasthash,1);
	BUILTIN(field,1);
	BUILTIN(objsetproto,2);
	BUILTIN(objgetproto,1);

	BUILTIN(int,1);
	BUILTIN(float,1);
	BUILTIN(string,1);
	BUILTIN(typeof,1);
	BUILTIN(closure,VAR_ARGS);
	BUILTIN(apply,VAR_ARGS);
	BUILTIN(varargs,1);
	BUILTIN(compare,2);
	BUILTIN(pcompare,2);
	BUILTIN(not,1);
	BUILTIN(throw,1);
	BUILTIN(rethrow,1);
	BUILTIN(nargs,1);
	BUILTIN(call,3);
	BUILTIN(isnan,1);
	BUILTIN(isinfinite,1);
	BUILTIN(istrue,1);

	BUILTIN(getkind,1);
	BUILTIN(iskind,2);

	BUILTIN(hnew,1);
	BUILTIN(hget,3);
	BUILTIN(hmem,3);
	BUILTIN(hset,4);
	BUILTIN(hadd,3);
	BUILTIN(hremove,3);
	BUILTIN(hresize,2);
	BUILTIN(hkey,1);
	BUILTIN(hcount,1);
	BUILTIN(hsize,1);
	BUILTIN(hiter,2);

	BUILTIN(iadd,2);
	BUILTIN(isub,2);
	BUILTIN(imult,2);
	BUILTIN(idiv,2);

	BUILTIN(excstack,0);
	BUILTIN(callstack,0);
	BUILTIN(version,0);
	BUILTIN(setresolver,1);
}
Example #8
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;
	}
}