1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
59 typedef __int64 int64;
61 typedef long long int64;
76 typedef val_t(*f_t)();
77 typedef int64(*call_t)();
79 static int get_uweic_type(type_expr* type)
82 #define _TYPE_CASE(x) case t_##x: return sizeof(x)
83 #define _TYPE_UCASE(x) case t_##x: case t_u##x: return sizeof(x)
101 return sizeof(void*);
105 s = (struct_t*)(type->u.inf);
121 static int get_size_arg_buffer( symentry_t* sym )
123 type_expr* ret_type = sym->type->nxt;
124 int arg_num = ((func_t*)sym->type->u.inf)->Num;
125 parm_t* arg_type = ((func_t*)sym->type->u.inf)->parm;
128 /* check for return type is no 1, 2, 4 or 8 bytes long */
129 switch( get_uweic_type( ret_type ) )
138 size += sizeof( void* );
140 for( int i = 0; i < arg_num; i++ )
141 size += (get_uweic_type( arg_type[i].type ) + 3) & ~3;
145 #pragma warning(disable:4716)
146 static float get_float(void)
150 static double get_double(void)
153 #pragma warning(default:4716)
155 static int callback_num = 0;
156 static callback_t* callback = (callback_t*)malloc( 10 );
157 static callback_t* current_call = 0;
159 static double set_double(double a)
165 typedef void(*set_double_t)(double);
167 set_double_t set_dbl = (set_double_t)set_double;
170 int64 unicall( int first )
172 int64 unicall( void* addr_ret, int first )
175 assert( current_call );
176 assert( current_call->sym );
180 symentry_t* sym = current_call->sym;
183 /* support __stdcall function */
185 char* r = (char*)*(&addr_ret - 1);
186 if( (*(unsigned short*)addr_ret) == 0xc481 || (*(unsigned short*)addr_ret) == 0xc483 )
187 /* __cdecl function */
188 *(unsigned short*)(r + 1) = 0;
189 else /* __stdcall function */
190 *(unsigned short*)(r + 1) = (unsigned short)get_size_arg_buffer( sym );
193 type_expr* ret_type = sym->type->nxt;
194 int arg_num = ((func_t*)sym->type->u.inf)->Num;
195 parm_t* parm = ((func_t*)sym->type->u.inf)->parm;
196 code_t* cb = ((func_t*)sym->type->u.inf)->callBack;
201 /* allocate buffer for return value if return value is structure or union */
202 if( ret_type->obj == t_struct || ret_type->obj == t_union )
204 ret_data = alloca( get_uweic_type( ret_type ) );
205 *(void**)(&(cb->inst[cb->nextinst - 5 - 2 * 0].val)) = ret_data;
209 char* buf = (char*)&first;
211 /* if sizeof(return value) not ... then first argument is pointer to data */
212 switch( get_uweic_type( ret_type ) )
221 buf += sizeof( void* );
224 for( int i = 0; i < arg_num; i++ )
226 switch( parm[i].type->obj )
230 *(void**)(&(cb->inst[cb->nextinst - 5 - 2 * (first_arg + i)].val)) = buf;
233 *(double*)(&(cb->inst[cb->nextinst - 5 - 2 * (first_arg + i)].val)) = *(double*)buf;
235 buf += (get_uweic_type( parm[i].type ) + 3) & ~3;
240 switch( get_uweic_type( ret_type ) )
248 if( ret_type->obj == t_float || ret_type->obj == t_double )
250 set_dbl( EiC_ReturnValue( double ) );
252 else if( ret_type->obj == t_struct || ret_type->obj == t_union )
254 return *EiC_ReturnValue( int64* );
257 return EiC_ReturnValue( int64 );
260 memcpy( &first, ret_data, get_uweic_type( ret_type ) );
265 static void* add_callback( symentry_t* sym )
268 for( i = 0; i < callback_num; i++ )
269 if( sym == callback[i].sym )
270 return callback[i].callcode;
271 callback = (callback_t*)realloc( callback, sizeof( callback_t ) * (callback_num + 1) );
272 callback[callback_num].sym = sym;
273 char* code = (char*)(callback[callback_num].callcode = malloc( 32 ));
275 code[0] = (unsigned char)0xc7; // mov current_sym, pointer
276 code[1] = (unsigned char)0x05;
277 *(void**)(code + 2) = ¤t_call;
278 *(callback_t**)(code + 2 + 4) = callback + callback_num;
280 code[2 + 4 + 4] = (unsigned char)0xe9; // jmp uniwrap
282 code[2 + 4 + 4] = (unsigned char)0xe8; // call uniwrap
284 int offset = (int)unicall - ((int)code + 15);
285 *(int*)(code + 2 + 4 + 4 + 1) = offset;
287 code[2 + 4 + 4 + 1 + 4] = (unsigned char)0xc2; // ret 0
288 code[2 + 4 + 4 + 1 + 5] = 0;
289 code[2 + 4 + 4 + 1 + 6] = 0;
290 code[2 + 4 + 4 + 1 + 7] = 0;
291 code[2 + 4 + 4 + 1 + 8] = 0;
295 mov current_sym, 12345678h; mov current_sym, 12345678h;
296 jmp unicall call unicall;
297 } ret 0; // this value may be changed if __stdcall
303 static called_type* current_func = 0;
307 assert( current_func );
308 assert( current_func->addr );
309 assert( current_func->sym );
311 called_type* func = current_func;
313 void* f = func->addr;
315 type_expr* ret_type = func->sym->type->nxt;
316 int arg_num = ((func_t*)func->sym->type->u.inf)->Num;
317 parm_t* arg_type = ((func_t*)func->sym->type->u.inf)->parm;
319 int size = get_size_arg_buffer( func->sym );
322 /* if return type is structure or union first argument is pointer to result */
323 if( ret_type->obj == t_struct || ret_type->obj == t_union )
326 /* calculating size of stack */
329 char* buffer = (char*)alloca( size );
334 /* if sizeof(result) not 1, 2, 4 or 8 alloc memory to save result */
335 /* set pointer ret_data to result data */
336 switch( get_uweic_type( ret_type ) )
346 *(void**)buf = malloc( get_uweic_type( ret_type ) );
347 buf += sizeof( void* );
348 ret_data = *(void**)buffer;
351 /* copy parameters values to stack es:esp */
352 for( i = 0; i < arg_num; i++ )
354 switch( arg_type[i].type->obj )
359 arg(first_arg + i, getargs(), ptr_t).p,
360 (get_uweic_type( arg_type[i].type ) + 3) & ~3 );
361 buf += (get_uweic_type( arg_type[i].type ) + 3) & ~3;
366 void* data = &arg(first_arg + i, getargs(), ptr_t).p;
367 int size = get_uweic_type( arg_type[i].type );
368 printf("size = %d value = %d\n", size, data ? *(int*)data : 0);
370 if( arg_type[i].type->nxt && arg_type[i].type->nxt->obj == t_funcdec )
372 printf("callback\n");
373 /* this is callback parameter, need special translation */
374 void* cb = arg(first_arg + i, getargs(), ptr_t).p;
375 symentry_t* sym = EiC_lookup_by_callback( 1, cb );
378 void* call = add_callback( sym );
387 void* data = &arg(first_arg + i, getargs(), ptr_t).p;
389 (get_uweic_type( arg_type[i].type ) + 3) & ~3 );
390 buf += (get_uweic_type( arg_type[i].type ) + 3) & ~3;
395 intbuf = ((call_t)f)();
400 mov dword ptr intbuf, eax
401 mov dword ptr intbuf + 4, edx
405 if( ret_type->obj == t_float )
407 *(float*)&intbuf = get_float();
409 else if( ret_type->obj == t_double )
411 *(double*)&intbuf = get_double();
414 switch( ret_type->obj )
418 memcpy( arg( 0, getargs(), ptr_t).p, ret_data, get_uweic_type( ret_type ) );
419 ret_val.p.sp = ret_val.p.p = arg( 0, getargs(), ptr_t).p;
420 ret_val.p.ep = (char*)ret_val.p.p + get_uweic_type( ret_type );
423 memcpy( &ret_val, ret_data, get_uweic_type( ret_type ) );
427 switch( get_uweic_type( ret_type ) )
436 free(*(void**)buffer);
442 int AddExternFunction( void* addr, char* name )
444 symentry_t* sym = (symentry_t*)EiC_lookup(1, name);
448 char* wrap = (char*)malloc( 16 + sizeof(called_type) );
450 called_type* func_desc = (called_type*)(wrap + 16);
451 func_desc->addr = addr;
452 func_desc->sym = sym;
454 wrap[0] = (unsigned char)0xc7; // mov cuurrent_sym, pointer
455 wrap[1] = (unsigned char)0x05;
456 *(void**)(wrap + 2) = ¤t_func;
457 *(called_type**)(wrap + 2 + 4) = func_desc;
458 /* in windows system we need support __stdcall function */
460 wrap[2 + 4 + 4] = (unsigned char)0xe9; // jmp uniwrap
461 int offset = (int)uniwrap - ((int)wrap + 15);
462 *(int*)(wrap + 2 + 4 + 4 + 1) = offset;
466 mov current_sym, 12345678h;
471 EiC_add_builtinfunc(name, (f_t)wrap);