void JitInstanceMemberFunction::compileThisAdjustementThunk( size_t a_uiThisOffset ) const
{
    o_assert(m_ThisAdjustmentThunks.find(a_uiThisOffset) == m_ThisAdjustmentThunks.end());

    size_t argCount = getSignature()->getParameterCount()+1; // parameters+this
    jit_value_t* args = o_allocate_n(argCount, jit_value_t); 

    // The fixing function has the same signature as the indirected one
    jit_function_t func = jit_function_create((jit_context_t)m_jit_context.context, jit_function_get_signature((jit_function_t)m_jit_function.function));

    jit_value_t new_this = jit_insn_add(func, jit_value_get_param(func, 0), jit_value_create_nint_constant(func, jit_type_nint, -((int)a_uiThisOffset)));

    args[0] = new_this;

    size_t i = 1;
    for(;i<argCount;++i)
    {
        args[i] = jit_value_get_param(func, i);
    }
    string name = "[thunk]:"+m_pSubroutine->getQualifiedDecoratedName()+":adjustor{"+boost::lexical_cast<string>(a_uiThisOffset)+"}";
    jit_insn_call(func
                , name.c_str()
                , (jit_function_t)m_jit_function.function
                , jit_function_get_signature((jit_function_t)m_jit_function.function)
                , args
                , argCount
                , 0);

    int result = jit_function_compile(func);
    o_assert(result != 0);

    o_deallocate_n(args, argCount, jit_value_t);

    m_ThisAdjustmentThunks[a_uiThisOffset] = func;
}
Exemplo n.º 2
0
/*
 * Create the slots for the fixed parameters of the current function.
 * Returns 0 on error else 1.
 */
static int _ILJitParamsCreate(ILJITCoder *coder)
{
	ILJitType signature = jit_function_get_signature(coder->jitFunction);

	if(signature)
	{
		ILJitLocalSlot *param = 0;
		ILUInt32 numParams = jit_type_num_params(signature);

#ifdef IL_JIT_THREAD_IN_SIGNATURE
		/* We don't include the ILExecThread in the params. */
		if(numParams > 1)
		{
			ILInt32 current = 0;

			/* Allocate the locals for the parameters */
			_ILJitLocalsAlloc(coder->jitParams, numParams - 1);

			for(current = 1; current < numParams; ++current)
			{
				param = _ILJitParamGet(coder, current - 1);

				param->value = jit_value_get_param(coder->jitFunction, current);
				param->flags = 0;
				param->refValue = 0;
			}
			coder->jitParams.numSlots = numParams - 1;
		}
#else
		if(numParams > 0)
		{
			ILInt32 current = 0;

			/* Allocate the locals for the parameters */
			_ILJitLocalsAlloc(coder->jitParams, numParams);

			for(current = 0; current < numParams; ++current)
			{
				param = _ILJitParamGet(coder, current);

				param->value = jit_value_get_param(coder->jitFunction, current);
				param->flags = 0;
				param->refValue = 0;
			}
			coder->jitParams.numSlots = numParams;
		}
#endif
		else
		{
			coder->jitParams.numSlots = 0;
		}
		return 1;
	}
	return 0;
}
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);
}