예제 #1
0
파일: quadl.hpp 프로젝트: fpelliccioni/nt2
 value_t quadlstep(const FUNC & f, const input_t & a,  const input_t & b,
                   const value_t &fa, const value_t& fb)
 {
   //  recursive core routine for function quadl.
   //  Evaluate integrand five times in interior of subinterval [a,b].
   input_t d = b-a;
   input_t c = nt2::average(a, b);
   input_t h = d*Half<real_t>();
   if (abs(h) < hmin_ || c == a || c == b ) //Minimum step size reached; singularity possible.
   {
     setwarn(1); return h*(fa+fb);
   }
   itab_t x = h*c1();
   x = c+x;
   vtab_t y = f(x);
   fcnt_ += 5;
   if (fcnt_ > maxfcnt_){ setwarn(2); return h*(fa+fb); }    // Maximum function count exceeded; singularity likely.
   itab_t x1 = nt2::cath(nt2::cath(a, x), b);  x = x1;
   vtab_t y1 = nt2::cath(nt2::cath(fa, y), fb);y = y1;
   value_t Q1 = h*nt2::globalsum(lobatto()*y(_(1, 2, 7)))*c245_; // Four point Lobatto quadrature times 1470.
   value_t Q = h*nt2::globalsum(kronrod()*y);                    // Seven point Kronrod refinement times 1470.
   if (nt2::is_invalid(Q)) { setwarn(3); return Q; }        // Infinite or Not-a-Number function value encountered.
   //  Check accuracy of integral over this subinterval.
   real_t curerr = nt2::abs(Q1 - Q);
   if (curerr <= tol_*nt2::abs(h))
   {
     err_+= curerr;
     setwarn(0);  return Q;
   }
   else //     % Subdivide into six subintervals.
   {
     setwarn(0);
     Q = Zero<value_t>();
     for(size_t k = 1; k <= 6; ++k)
     {
       Q += quadlstep(f, x(k), x(k+1), y(k), y(k+1));
     }
     return Q;
   }
 };
예제 #2
0
bool assembler::compile_call(asmgen & asg, const func_binary & fb, command cmd)
{
	int calltype = COMMAND_CODE(GET_CMD(fb, m_pos));
	m_pos++;

	if (calltype == CALL_FAKE)
	{
		setwarn(m_fk, "assembler not supprt fake call, change to normal call");
		calltype = CALL_NORMAL;
	}
	
	if (calltype == CALL_NORMAL)
	{
		int callpos = 0;
		GET_VARIANT_POS(fb, callpos, m_pos);
		m_pos++;

		int retnum = COMMAND_CODE(GET_CMD(fb, m_pos));
		m_pos++;

		std::vector<int> retvec;
		for (int i = 0; i < retnum; i++)
		{
			int ret = 0;
			GET_VARIANT_POS(fb, ret, m_pos);
			m_pos++;
			retvec.push_back(ret);
		}
		
		int argnum = COMMAND_CODE(GET_CMD(fb, m_pos));
		m_pos++;

		// 1.塞参数
		asg.variant_ps_clear();
		for (int i = 0; i < argnum; i++)
		{
			int arg = 0;
			GET_VARIANT_POS(fb, arg, m_pos);
			m_pos++;
			
			asg.variant_push(arg);
		}

		// 2.准备调用函数
		// 3.调用
		asg.call_func_param2((void *)&machine::static_call, m_fk, callpos);

		// 4.处理返回值
		for (int i = (int)retvec.size() - 1; i >= 0; i--)
		{
			int ret = retvec[i];
			asg.variant_pop(ret);
		}

		// 5.清理不需要的
		asg.variant_ps_clear();
	}
	else if (calltype == CALL_CLASSMEM)
	{
		int callpos = 0;
		GET_VARIANT_POS(fb, callpos, m_pos);
		m_pos++;

		int retnum = COMMAND_CODE(GET_CMD(fb, m_pos));
		m_pos++;

		std::vector<int> retvec;
		for (int i = 0; i < retnum; i++)
		{
			int ret = 0;
			GET_VARIANT_POS(fb, ret, m_pos);
			m_pos++;
			retvec.push_back(ret);
		}

		int argnum = COMMAND_CODE(GET_CMD(fb, m_pos));
		m_pos++;

		// 0.取出实际的函数名
		int classpos = 0;
		GET_VARIANT_POS(fb, classpos, m_pos + argnum - 1);
		int tmppos = 0;
		GET_TMP_POS(fb, tmppos);
		
		asg.call_func_param3((void*)&assembler_get_classmem_call, m_fk, classpos, callpos);
		asg.variant_from_rax(tmppos);

		// 1.塞参数
		asg.variant_ps_clear();
		for (int i = 0; i < argnum; i++)
		{
			int arg = 0;
			GET_VARIANT_POS(fb, arg, m_pos);
			m_pos++;
			
			asg.variant_push(arg);
		}

		// 2.准备调用函数
		// 3.调用
		asg.call_func_param2((void *)&machine::static_call, m_fk, tmppos);

		// 4.处理返回值
		for (int i = (int)retvec.size() - 1; i >= 0; i--)
		{
			int ret = retvec[i];
			asg.variant_pop(ret);
		}

		// 5.清理不需要的
		asg.variant_ps_clear();
	}
	
	return true;
}
예제 #3
0
bool assembler::compile_next(asmgen & asg, const func_binary & fb)
{
	command cmd = GET_CMD(fb, m_pos);
	int type = COMMAND_TYPE(cmd);
	int code = COMMAND_CODE(cmd);

	USE(type);
	FKLOG("[assembler] compile_next cmd %d %d %s", type, code, OpCodeStr(code));
		
	assert (type == COMMAND_OPCODE);

	m_pos++;

	m_conposnum = 0;
	memset(m_conpos, 0, sizeof(m_conpos));

	bool ret = false;
	USE(ret);
	// 执行对应命令,放一起switch效率更高,cpu有缓存
	switch (code)
	{
	case OPCODE_ASSIGN:
		{
			ret = compile_assign(asg, fb, cmd);
		}
		break;
	case OPCODE_RETURN:
		{
			ret = compile_return(asg, fb, cmd);
		}
		break;
	case OPCODE_PLUS:
	case OPCODE_MINUS:
	case OPCODE_MULTIPLY:
	case OPCODE_DIVIDE:
	case OPCODE_DIVIDE_MOD:
		{
			ret = compile_math(asg, fb, cmd);
		}
		break;
	case OPCODE_PLUS_ASSIGN:
	case OPCODE_MINUS_ASSIGN:
	case OPCODE_MULTIPLY_ASSIGN:
	case OPCODE_DIVIDE_ASSIGN:
	case OPCODE_DIVIDE_MOD_ASSIGN:
		{
			ret = compile_math_assign(asg, fb, cmd);
		}
		break;
	case OPCODE_AND:
	case OPCODE_OR:
	case OPCODE_LESS:
	case OPCODE_MORE:
	case OPCODE_EQUAL:
	case OPCODE_MOREEQUAL:
	case OPCODE_LESSEQUAL:
	case OPCODE_NOTEQUAL:
		{
			ret = compile_cmp(asg, fb, cmd);
		}
		break;
	case OPCODE_AND_JNE:
	case OPCODE_OR_JNE:
	case OPCODE_LESS_JNE:
	case OPCODE_MORE_JNE:
	case OPCODE_EQUAL_JNE:
	case OPCODE_MOREEQUAL_JNE:
	case OPCODE_LESSEQUAL_JNE:
	case OPCODE_NOTEQUAL_JNE:
		{
			ret = compile_cmp_jne(asg, fb, cmd);
		}
		break;
	case OPCODE_NOT:
		{
			ret = compile_single(asg, fb, cmd);
		}
		break;
	case OPCODE_NOT_JNE:
		{
			ret = compile_single_jne(asg, fb, cmd);
		}
		break;
	case OPCODE_JNE:
		{
			ret = compile_jne(asg, fb, cmd);
		}
		break;
	case OPCODE_JMP:
		{
			ret = compile_jmp(asg, fb, cmd);
		}
		break;
	case OPCODE_CALL:
		{
			ret = compile_call(asg, fb, cmd);
		}
		break;
	case OPCODE_SLEEP:
	case OPCODE_YIELD:
		{
			setwarn(m_fk, "assembler only support SLEEP or YIELD, skip code");
			ret = true;
			m_pos++;
		}
		break;
	case OPCODE_FORBEGIN:
	case OPCODE_FORLOOP:
		{
			FKERR("assembler dont support for i -> n, j");
			compile_seterror(fb, cmd, efk_jit_error, "assembler dont support for i -> n, j");
			return false;
		}
		break;
	default:
		assert(0);
		FKERR("[assembler] compile_next err code %d %s", code, OpCodeStr(code));
		compile_seterror(fb, cmd, efk_jit_error, "compile_next err code %d %s", code, OpCodeStr(code));
		return false;
	}
	return ret;
}
예제 #4
0
/*
 * Sys call to allow users to find out
 * their current position wrt quota's
 * and to allow super users to alter it.
 */
qquota()
{
	register struct a {
		int	cmd;
		int	uid;
		int	arg;
		caddr_t	addr;
	} *uap = (struct a *)u.u_ap;
	register struct quota *q;

#ifndef QUOTA
	u.u_error = EINVAL;
	return;
#else
	if (uap->uid < 0)
		uap->uid = u.u_ruid;
	if (uap->uid != u.u_ruid && uap->uid != u.u_quota->q_uid && !suser())
		return;
	if (uap->cmd != Q_SYNC && uap->cmd != Q_SETUID) {
		q = getquota((uid_t)uap->uid, uap->cmd == Q_DOWARN, 0);
		if (q == NOQUOTA) {
			u.u_error = ESRCH;
			return;
		}
		if (u.u_error)
			goto bad;
	}
	switch (uap->cmd) {

	case Q_SETDLIM:
		u.u_error = setdlim(q, (dev_t)uap->arg, uap->addr);
		break;

	case Q_GETDLIM:
		u.u_error = getdlim(q, (dev_t)uap->arg, uap->addr);
		break;

	case Q_SETDUSE:
		u.u_error = setduse(q, (dev_t)uap->arg, uap->addr);
		break;

	case Q_SETWARN:
		u.u_error = setwarn(q, (dev_t)uap->arg, uap->addr);
		break;

	case Q_DOWARN:
		u.u_error = dowarn(q, (dev_t)uap->arg);
		break;
	
	case Q_SYNC:
		u.u_error = qsync((dev_t)uap->arg);
		return;

	case Q_SETUID:
		u.u_error = qsetuid((uid_t)uap->uid, uap->arg);
		return;

	default:
		u.u_error = EINVAL;
		break;
	}
bad:
	delquota(q);
#endif
}