Exemplo n.º 1
0
/*
 * Upon a system call, the stack will look like:
 *
 * sp+32   parm1
 * sp+28   parm0
 * sp+24   return value
 * sp+20   return address
 * sp+16   local1
 * sp+14   local0
 * sp+12   arg1
 * sp+8    arg0
 * sp+4    return stack
 * sp      return address
 *
 * An interpreted function will immediately execute an OP_ENTER instruction,
 * which will subtract space for locals from sp
 */
intptr_t QDECL VM_CallFunc(vm_t *vm, int callnum, ...)
{
	vm_t     *oldVM;
	intptr_t r;

	if (!vm)
	{
		Com_Error(ERR_FATAL, "VM_Call: NULL vm");
	}

	oldVM     = currentVM;
	currentVM = vm;
	lastVM    = vm;

	if (vm_debugLevel)
	{
		Com_Printf("VM_Call( %i )\n", callnum);
	}

	// if we have a dll loaded, call it directly
	if (vm->entryPoint)
	{
		// rcg010207 -  see dissertation at top of VM_DllSyscall() in this file.
		intptr_t args[VM_SYSCALL_ARGS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
		va_list  ap;
		int      i;

		va_start(ap, callnum);
		for (i = 0; i < ARRAY_LEN(args); i++)
		{
			// We add the end of args point since windows at least just returns random values if there are no args
			// this way we know that only valid values are sent to the vm
			args[i] = va_arg(ap, intptr_t);
			if (args[i] == VM_CALL_END)
			{
				args[i] = 0;
				break;
			}
		}
		va_end(ap);

		r = vm->entryPoint(callnum, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7],
		                   args[8], args[9], args[10], args[11], args[12], args[13], args[14], args[15]);
	}
#if 0
	else if (vm->compiled)
	{
		r = VM_CallCompiled(vm, &callnum);
	}
	else
	{
		r = VM_CallInterpreted(vm, &callnum);
	}
#else
	else
	{
Exemplo n.º 2
0
intptr_t QDECL VM_Call( vm_t *vm, intptr_t callnum, ... ) {
	vm_t    *oldVM;
	intptr_t r;
#if ( defined __linux__ )// use "safer" ppc version
	int i;
	intptr_t args[16];
	va_list ap;
#endif


	if ( !vm ) {
		Com_Error( ERR_FATAL, "VM_Call with NULL vm" );
	}

	oldVM = currentVM;
	currentVM = vm;
	lastVM = vm;

	if ( vm_debugLevel ) {
		Com_Printf( "VM_Call( %i )\n", callnum );
	}

	// if we have a dll loaded, call it directly
	if ( vm->entryPoint ) {
#if ( defined __linux__ )// use "safer" ppc version
		va_start( ap, callnum );
		for ( i = 0; i < sizeof( args ) / sizeof( args[i] ); i++ )
			args[i] = va_arg( ap, intptr_t );
		va_end( ap );

		r = vm->entryPoint( callnum,  args[0],  args[1],  args[2], args[3],
							args[4],  args[5],  args[6], args[7],
							args[8],  args[9], args[10], args[11],
							args[12], args[13], args[14], args[15] );
#else // PPC above, original id code below
		r = vm->entryPoint( ( &callnum )[0], ( &callnum )[1], ( &callnum )[2], ( &callnum )[3],
							( &callnum )[4], ( &callnum )[5], ( &callnum )[6], ( &callnum )[7],
							( &callnum )[8],  ( &callnum )[9],  ( &callnum )[10],  ( &callnum )[11],  ( &callnum )[12] );
#endif
	} else if ( vm->compiled ) {
		r = VM_CallCompiled( vm, &callnum );
	} else {
		r = VM_CallInterpreted( vm, &callnum );
	}

	if ( oldVM != NULL ) { // bk001220 - assert(currentVM!=NULL) for oldVM==NULL
		currentVM = oldVM;
	}
	return r;
}