void JitInstanceMemberFunction::compileVTableIndirectionFunction()
{
    m_jit_virtual_indirection_function = jit_function_create((jit_context_t)m_jit_context.context, toJitSignature(m_eAbi, getSignature()));
    o_assert(m_jit_virtual_indirection_function.function);
    jit_context_build_start((jit_context_t)m_jit_context.context);
    size_t argCount = getSignature()->getParameterCount()+1; // parameters+this
    jit_value_t* args = o_allocate_n(argCount, jit_value_t); 

    // The indirection has the same signature as the indirected one
    jit_value_t this_pointer = jit_value_get_param((jit_function_t)m_jit_virtual_indirection_function.function, 0);
    jit_value_t vtable_index = jit_value_create_nint_constant((jit_function_t)m_jit_virtual_indirection_function.function, jit_type_nuint, getInstanceMemberFunction()->getVirtualTableIndex());
    jit_value_t vtable_array = jit_insn_load_relative ((jit_function_t)m_jit_virtual_indirection_function.function, this_pointer, 0, jit_type_void_ptr);
    jit_value_t vtable_pointer = jit_insn_load_elem((jit_function_t)m_jit_virtual_indirection_function.function, vtable_array, vtable_index, jit_type_void_ptr);

    size_t i = 0;
    for(;i<argCount;++i)
    {
        args[i] = jit_value_get_param((jit_function_t)m_jit_virtual_indirection_function.function, i);
    }

    jit_insn_call_indirect_vtable ((jit_function_t)m_jit_virtual_indirection_function.function, vtable_pointer, jit_function_get_signature((jit_function_t)m_jit_function.function), args, argCount, 0);

    int result = jit_function_compile((jit_function_t)m_jit_virtual_indirection_function.function);
    o_assert(result != 0);
    
    jit_context_build_end((jit_context_t)m_jit_context.context);

    o_deallocate_n(args, argCount, jit_value_t);
}
Beispiel #2
0
jit_value jit_function::insn_load_elem
	(const jit_value& base_addr, const jit_value& index,
	 jit_type_t elem_type)
{
	value_wrap(jit_insn_load_elem
		(func, base_addr.raw(), index.raw(), elem_type));
}
Beispiel #3
0
/*
 * Inline function to get the character at the specified indexe in a
 * string.
 */
static int _ILJitSystemStringChars(ILJITCoder *jitCoder,
								   ILMethod *method,
								   ILCoderMethodInfo *methodInfo,
								   ILJitStackItem *args,
								   ILInt32 numArgs)
{
	ILJitFunction jitFunction = ILJitFunctionFromILMethod(method);
	ILClass *stringClass = ILMethod_Owner(method);
	ILJitValue length;
	ILJitValue stringBase;
	ILJitValue returnValue;

	if(!jitFunction)
	{
		/* We need to layout the class first. */
		if(!_LayoutClass(ILExecThreadCurrent(), stringClass))
		{
			return 0;
		}
		if(!(jitFunction = ILJitFunctionFromILMethod(method)))
		{
			return 0;
		}
	}

#if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS) && defined(_IL_JIT_ENABLE_DEBUG)
	if(jitCoder->flags & IL_CODER_FLAG_STATS)
	{
		ILMutexLock(globalTraceMutex);
		fprintf(stdout, "Inline System.String::get_Chars\n");
		ILMutexUnlock(globalTraceMutex);
	}
#endif

	_ILJitStackItemCheckNull(jitCoder, args[0]);
	length = _ILJitStringGetLength(jitCoder->jitFunction,
								   _ILJitStackItemValue(args[0]));
	JITC_START_CHECK_STRING_INDEX(jitCoder, length, _ILJitStackItemValue(args[1]))
	stringBase = _ILJitStringGetStart(jitCoder->jitFunction,
									  _ILJitStackItemValue(args[0]));
	returnValue = jit_insn_load_elem(jitCoder->jitFunction,
									 stringBase,
									 _ILJitStackItemValue(args[1]),
									 _IL_JIT_TYPE_CHAR);
	JITC_END_CHECK_STRING_INDEX(jitCoder)

	_ILJitStackPushValue(jitCoder, returnValue);
	return 1;
}
Beispiel #4
0
jit_function_t GPerlJITCompiler::compile(JITParam *param)
{
	GPerlVirtualMachineCode *pc = param->mtd;
	jit_context_t ctx = jit_context_create();
	jit_context_build_start(ctx);
	int argc = param->argc;
	jit_type_t _params[argc];
	for (int i = 0; i < argc; i++) {
		_params[i] = getJitType(param->arg_types[i]);
	}
	jit_type_t rtype = getJitType(param->return_type);
	jit_value_t curstack[32] = {0};
	jit_value_t argstack[MAX_ARGSTACK_SIZE] = {0};
	jit_type_t signature = jit_type_create_signature(jit_abi_fastcall, rtype, _params, argc, 0);
	jit_function_t func = jit_function_create(ctx, signature);
	jit_value_t _v[MAX_REG_SIZE] = {0};
	GPerlJmpStack *jmp_stack = new GPerlJmpStack();
	argc = 0;
	for (; pc->op != UNDEF; pc++) {
		if (jmp_stack->isJmp()) {
			GPerlJmpInfo *inf = jmp_stack->pop();
			jit_insn_label(func, &inf->label);
		}
		switch (pc->op) {
		case LET:
			DBG_PL("COMPILE LET");
			curstack[pc->dst] = _v[pc->src];
			break;
		case MOV:
			DBG_PL("COMPILE MOV");
			_v[pc->dst] = compileMOV(pc, &func);
			break;
		case ARRAY_ARGAT: {
			DBG_PL("COMPILE ARGAT");
			jit_value_t arg = jit_value_get_param(func, pc->src);
			jit_nint offset = 48;
			jit_value_t list = jit_insn_load_relative(func, arg, offset, object_ptr_type);
			jit_value_t idx = jit_value_create_nint_constant(func, jit_type_int, pc->idx);
			jit_value_t elem = jit_insn_load_elem(func, list, idx, value_type);
			_v[pc->dst] = elem;
			break;
		}
		case vMOV:
			DBG_PL("COMPILE vMOV");
			_v[pc->dst] = curstack[pc->src];
			break;
		case gMOV:
			break;
		case ARGMOV:
			DBG_PL("COMPILE ARGMOV");
			_v[pc->dst] = jit_value_get_param(func, pc->src);
			break;
		case ADD:
			DBG_PL("COMPILE ADD");
			_v[pc->dst] = jit_insn_add(func, _v[pc->dst], _v[pc->src]);
			break;
		case SUB:
			DBG_PL("COMPILE SUB");
			_v[pc->dst] = jit_insn_sub(func, _v[pc->dst], _v[pc->src]);
			break;
		case iADDC: {
			DBG_PL("COMPILE iADDC");
			jit_value_t c = jit_value_create_nint_constant(func, jit_type_int, pc->v.ivalue);
			_v[pc->dst] = jit_insn_add(func, _v[pc->dst], c);
			break;
		}
		case iSUBC: {
			DBG_PL("COMPILE iSUBC");
			jit_value_t c = jit_value_create_nint_constant(func, jit_type_int, pc->v.ivalue);
			_v[pc->dst] = jit_insn_sub(func, _v[pc->dst], c);
			break;
		}
		case IS: {
			DBG_PL("COMPILE IS");
			jit_value_t c = jit_value_create_nint_constant(func, jit_type_int, 1);
			jit_value_t tmp = jit_insn_eq(func, _v[pc->dst], c);
			GPerlJmpInfo *inf = new GPerlJmpInfo(pc->jmp);
			jmp_stack->push(inf);
			jit_insn_branch_if_not(func, tmp, &inf->label);
			break;
		}
		case iJLC: {
			DBG_PL("COMPILE iJLC");
			jit_value_t c = jit_value_create_nint_constant(func, jit_type_int, pc->v.ivalue);
			jit_value_t tmp = jit_insn_lt(func, _v[pc->dst], c);
			GPerlJmpInfo *inf = new GPerlJmpInfo(pc->jmp);
			jmp_stack->push(inf);
			jit_insn_branch_if_not(func, tmp, &inf->label);
			break;
		}
		case iJLEC: {
			DBG_PL("COMPILE iJLEC");
			jit_value_t c = jit_value_create_nint_constant(func, jit_type_int, pc->v.ivalue);
			jit_value_t tmp = jit_insn_le(func, _v[pc->dst], c);
			GPerlJmpInfo *inf = new GPerlJmpInfo(pc->jmp);
			jmp_stack->push(inf);
			jit_insn_branch_if_not(func, tmp, &inf->label);
			break;
		}
		case JE: {
			DBG_PL("COMPILE JE");
			jit_value_t tmp = jit_insn_eq(func, _v[pc->dst], _v[pc->src]);
			GPerlJmpInfo *inf = new GPerlJmpInfo(pc->jmp);
			jmp_stack->push(inf);
			jit_insn_branch_if_not(func, tmp, &inf->label);
			break;
		}
		case JLE: {
			DBG_PL("COMPILE JLE");
			jit_value_t tmp = jit_insn_le(func, _v[pc->dst], _v[pc->src]);
			GPerlJmpInfo *inf = new GPerlJmpInfo(pc->jmp);
			jmp_stack->push(inf);
			jit_insn_branch_if_not(func, tmp, &inf->label);
			break;
		}
		case PUSH:
			DBG_PL("COMPILE PUSH");
			argstack[pc->src] = _v[pc->dst];
			argc++;
			break;
		case SELFCALL: {
			DBG_PL("COMPILE SELFCALL");
			_v[pc->dst] = jit_insn_call(func, "", func, NULL, argstack, argc, 0);//JIT_CALL_TAIL);
			argc = 0;
			break;
		}
		case SELF_FASTCALL0: {
			DBG_PL("COMPILE SELF_FASTCALL0");
			argstack[0] = _v[pc->arg0];
			_v[pc->dst] = jit_insn_call(func, "", func, NULL, argstack, 1, 0);//JIT_CALL_TAIL);
			break;
		}
		case SELF_FASTCALL1: {
			DBG_PL("COMPILE SELF_FASTCALL1");
			argstack[0] = _v[pc->arg0];
			argstack[1] = _v[pc->arg1];
			_v[pc->dst] = jit_insn_call(func, "", func, NULL, argstack, 2, 0);//JIT_CALL_TAIL);
			break;
		}
		case SELF_FASTCALL2: {
			DBG_PL("COMPILE SELF_FASTCALL2");
			argstack[0] = _v[pc->arg0];
			argstack[1] = _v[pc->arg1];
			argstack[2] = _v[pc->arg2];
			_v[pc->dst] = jit_insn_call(func, "", func, NULL, argstack, 3, 0);//JIT_CALL_TAIL);
			break;
		}
		case SELF_FASTCALL3: {
			DBG_PL("COMPILE SELF_FASTCALL3");
			argstack[0] = _v[pc->arg0];
			argstack[1] = _v[pc->arg1];
			argstack[2] = _v[pc->arg2];
			argstack[3] = _v[pc->arg3];
			_v[pc->dst] = jit_insn_call(func, "", func, NULL, argstack, 4, 0);//JIT_CALL_TAIL);
			break;
		}
		case REF: {
			//int ret = 0;
			//if (TYPE_CHECK(v) > 1) {
			//GPerlObject *o = (GPerlObject *)getObject(v);
			//if (o->h.type == ArrayRef) {
			//ret = 1;
			//}
			//}
			//INT_init(reg[0], ret);
			break;
		}
		case RET: case JIT_COUNTDOWN_RET:
			DBG_PL("COMPILE RET");
			_v[0] = _v[pc->src];
			jit_insn_return(func, _v[0]);
			break;
		default:
			DBG_PL("COMPILE DEFALUT");
			break;
		}
	}
	jit_function_compile(func);
	jit_context_build_end(ctx);
	return func;
}