# Patch created by krokas
# Date: Wed Oct 17 14:34:06 MSD 2007
# Repository: libjit
# Comments:
# 
#### End of Preamble ####

#### Patch data follows ####
Index: include/jit/jit-function.h
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/include/jit/jit-function.h,v
retrieving revision 1.6
diff -c -r1.6 jit-function.h
*** include/jit/jit-function.h	7 Oct 2007 14:16:50 -0000	1.6
--- include/jit/jit-function.h	17 Oct 2007 10:34:04 -0000
***************
*** 76,82 ****
  	(jit_function_t func) JIT_NOTHROW;
  unsigned int jit_function_get_max_optimization_level(void) JIT_NOTHROW;
  jit_label_t jit_function_reserve_label(jit_function_t func) JIT_NOTHROW;
! 
  #ifdef	__cplusplus
  };
  #endif
--- 76,83 ----
  	(jit_function_t func) JIT_NOTHROW;
  unsigned int jit_function_get_max_optimization_level(void) JIT_NOTHROW;
  jit_label_t jit_function_reserve_label(jit_function_t func) JIT_NOTHROW;
! jit_function_t jit_function_create_cdecl_trampoline
! 		(jit_context_t context, jit_type_t signature) JIT_NOTHROW;
  #ifdef	__cplusplus
  };
  #endif
Index: jit/jit-function.c
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-function.c,v
retrieving revision 1.31
diff -c -r1.31 jit-function.c
*** jit/jit-function.c	7 Oct 2007 14:16:50 -0000	1.31
--- jit/jit-function.c	17 Oct 2007 10:34:05 -0000
***************
*** 55,60 ****
--- 55,61 ----
  #if defined(jit_redirector_size) || defined(jit_indirector_size)
  	jit_cache_t cache;
  #endif
+ 	jit_abi_t abi;
  
  	/* Allocate memory for the function and clear it */
  	func = jit_cnew(struct _jit_function);
***************
*** 139,144 ****
--- 140,151 ----
  	}
  	context->last_function = func;
  
+ 	func->cdecl_trampoline = 0;
+ 	abi = jit_type_get_abi(signature);
+ 	if(abi != jit_abi_cdecl)
+ 	{
+ 		func->cdecl_trampoline = jit_function_create_cdecl_trampoline(context, signature);
+ 	}
  	/* Return the function to the caller */
  	return func;
  }
***************
*** 1492,1497 ****
--- 1499,1520 ----
  
  int jit_function_apply(jit_function_t func, void **args, void *return_area)
  {
+ 	jit_type_t signature = jit_function_get_signature(func);
+ 	jit_abi_t abi = jit_type_get_abi(signature);
+ 	if(abi != jit_abi_cdecl)
+ 	{
+ 		int num_params = jit_type_num_params(signature);
+ 		int index;
+ 		void *trampoline_args[num_params + 1];
+ 		for(index = 0; index < num_params; index++)
+ 		{
+ 			trampoline_args[index] = args[index];
+ 		}
+ 		void *func_ptr = jit_function_to_closure(func);
+ 		trampoline_args[num_params] = &func_ptr;
+ 		return jit_function_apply(func->cdecl_trampoline, trampoline_args, return_area);
+ 	}
+ 
  	if(func)
  	{
  		return jit_function_apply_vararg
***************
*** 1655,1657 ****
--- 1678,1711 ----
  
  	return (func->builder->next_label)++;
  }
+ 
+ 
+ jit_function_t jit_function_create_cdecl_trampoline(jit_context_t context, jit_type_t signature)
+ {
+ 	int num_params = jit_type_num_params(signature);
+ 	int index;
+ 	jit_type_t params[num_params + 1];
+ 	jit_value_t args[num_params];
+ 	for(index = 0; index < num_params; index++)
+ 	{
+ 		params[index] = jit_type_get_param(signature, index);
+ 	}
+ 	params[num_params] = jit_type_void_ptr;
+ 	jit_type_t return_type = jit_type_get_return(signature);
+ 	jit_type_t trampoline_signature = jit_type_create_signature
+ 		    (jit_abi_cdecl, return_type, params, num_params + 1, 1);
+ 	jit_function_t trampoline = jit_function_create(context, trampoline_signature);
+ 	for(index = 0; index < num_params; index++)
+ 	{
+ 		args[index] = jit_value_get_param(trampoline, index);
+ 	}
+ 	jit_value_t return_value = jit_insn_call_indirect(trampoline,
+ 							    jit_value_get_param(trampoline, num_params),
+ 							    signature,
+ 							    args,
+ 							    num_params,
+ 							    0);
+ 	jit_insn_return(trampoline, return_value);
+ 	jit_function_compile(trampoline);
+ 	return trampoline;
+ }
Index: jit/jit-internal.h
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-internal.h,v
retrieving revision 1.28
diff -c -r1.28 jit-internal.h
*** jit/jit-internal.h	4 Feb 2007 14:31:33 -0000	1.28
--- jit/jit-internal.h	17 Oct 2007 10:34:07 -0000
***************
*** 409,414 ****
--- 409,418 ----
  	   stored in the entry_point field. Indirectors are used
  	   to support recompilation and on-demand compilation. */
  	unsigned char		*indirector;
+ 	
+ 	/* Trampoline with CDECL ABI used with jit_function_apply
+ 	   for functions under different ABI */
+ 	jit_function_t		cdecl_trampoline;
  };
  
  /*
#### End of Patch data ####
