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; }
/* * 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); }