Ejemplo n.º 1
0
EXTERN value neko_vm_execute( neko_vm *vm, void *_m ) {
	unsigned int i;
	neko_module *m = (neko_module*)_m;
	value old_env = vm->env, ret;
	value old_this = vm->vthis;
	neko_vm_select(vm);
	for(i=0;i<m->nfields;i++)
		val_id(val_string(m->fields[i]));
	vm->env = alloc_array(0);
	vm->vthis = val_null;
	ret = neko_interp(vm,m,(int_val)val_null,m->code);
	vm->env = old_env;
	vm->vthis = old_this;
	return ret;
}
Ejemplo n.º 2
0
EXTERN value val_callEx( value vthis, value f, value *args, int nargs, value *exc ) {
	neko_vm *vm = NEKO_VM();
	value old_this = vm->vthis;
	value old_env = vm->env;
	value ret = val_null;
	jmp_buf oldjmp;
	if( vthis != NULL )
		vm->vthis = vthis;
	if( exc ) {
		memcpy(&oldjmp,&vm->start,sizeof(jmp_buf));
		if( setjmp(vm->start) ) {
			*exc = vm->vthis;
			neko_process_trap(vm);
			vm->vthis = old_this;
			vm->env = old_env;
			memcpy(&vm->start,&oldjmp,sizeof(jmp_buf));
			return val_null;
		}
		neko_setup_trap(vm);
	}
	if( (uintptr_t)&vm < (uintptr_t)vm->c_stack_max )
		val_throw(alloc_string("C Stack Overflow"));
	if( val_is_int(f) )
		val_throw(alloc_string("Invalid call"));
	if( val_tag(f) == VAL_PRIMITIVE ) {
		vm->env = ((vfunction *)f)->env;
		if( nargs == ((vfunction*)f)->nargs ) {
			if( nargs > CALL_MAX_ARGS )
				failure("Too many arguments for a call");
			switch( nargs ) {
			case 0:
				ret = ((c_prim0)((vfunction*)f)->addr)();
				break;
			case 1:
				ret = ((c_prim1)((vfunction*)f)->addr)(args[0]);
				break;
			case 2:
				ret = ((c_prim2)((vfunction*)f)->addr)(args[0],args[1]);
				break;
			case 3:
				ret = ((c_prim3)((vfunction*)f)->addr)(args[0],args[1],args[2]);
				break;
			case 4:
				ret = ((c_prim4)((vfunction*)f)->addr)(args[0],args[1],args[2],args[3]);
				break;
			case 5:
				ret = ((c_prim5)((vfunction*)f)->addr)(args[0],args[1],args[2],args[3],args[4]);
				break;
			}
		} else if( ((vfunction*)f)->nargs == -1 )
			ret = (value)((c_primN)((vfunction*)f)->addr)(args,nargs);
		else
			val_throw(alloc_string("Invalid call"));		
		if( ret == NULL )
			val_throw( (value)((vfunction*)f)->module );		
	} else if( val_short_tag(f) == VAL_FUNCTION ) {
		if( nargs == ((vfunction*)f)->nargs )  {
			int n;
			if( vm->csp + 4 >= vm->sp - nargs && !neko_stack_expand(vm->sp,vm->csp,vm) ) {
				if( exc ) {
					neko_process_trap(vm);
					memcpy(&vm->start,&oldjmp,sizeof(jmp_buf));	
				}
				failure("Stack Overflow");
			} else {
				for(n=0;n<nargs;n++)
					*--vm->sp = (int_val)args[n];
				vm->env = ((vfunction*)f)->env;
				if( val_tag(f) == VAL_FUNCTION ) {
					*++vm->csp = (int_val)callback_return;
					*++vm->csp = 0;
					*++vm->csp = 0;
					*++vm->csp = 0;
					ret = neko_interp(vm,((vfunction*)f)->module,(int_val)val_null,(int_val*)((vfunction*)f)->addr);
				} else {
					neko_module *m = (neko_module*)((vfunction*)f)->module;
					ret = ((jit_prim)jit_boot_seq)(vm,((vfunction*)f)->addr,val_null,m);			
				}
			}
		}
		else
			val_throw(alloc_string("Invalid call"));
	} else
		val_throw(alloc_string("Invalid call"));
	if( exc ) {
		neko_process_trap(vm);
		memcpy(&vm->start,&oldjmp,sizeof(jmp_buf));	
	}
	vm->vthis = old_this;
	vm->env = old_env;
	return ret;
}