Просмотр исходного кода

Replaced as_callfunc_x86.cpp with unmodified version from the SDK.

Lasse Öörni 14 лет назад
Родитель
Сommit
cae6b1eff5
1 измененных файлов с 41 добавлено и 28 удалено
  1. 41 28
      ThirdParty/AngelScript/source/as_callfunc_x86.cpp

+ 41 - 28
ThirdParty/AngelScript/source/as_callfunc_x86.cpp

@@ -28,7 +28,6 @@
    [email protected]
 */
 
-// Modified by Lasse Öörni for Urho3D
 
 //
 // as_callfunc_x86.cpp
@@ -50,6 +49,29 @@
 
 BEGIN_AS_NAMESPACE
 
+//
+// With some compile level optimizations the functions don't clear the FPU
+// stack themselves. So we have to do it as part of calling the native functions, 
+// as the compiler will not be able to predict when it is supposed to do it by 
+// itself due to the dynamic nature of scripts
+//
+// - fninit clears the FPU stack and the FPU control word
+// - emms only clears the FPU stack, while preserving the FPU control word
+//
+// By default I use fninit as it seems to be what works for most people,
+// but some may find it necessary to define this as emms instead.
+//
+// TODO: Figure out when one or the other must be used, and a way to
+//       configure this automatically in as_config.h
+//
+#ifndef CLEAR_FPU_STACK
+#define CLEAR_FPU_STACK fninit
+#endif
+
+// These macros are just to allow me to use the above macro in the GNUC style inline assembly
+#define _S(x) _TOSTRING(x)
+#define _TOSTRING(x) #x
+
 typedef asQWORD (*t_CallCDeclQW)(const asDWORD *, int, size_t);
 typedef asQWORD (*t_CallCDeclQWObj)(void *obj, const asDWORD *, int, size_t);
 typedef asDWORD (*t_CallCDeclRetByRef)(const asDWORD *, int, size_t, void *);
@@ -245,8 +267,7 @@ void NOINLINE CallCDeclFunction(const asDWORD *args, int paramSize, size_t func)
 		push ecx
 
 		// Clear the FPU stack, in case the called function doesn't do it by itself
-		// Use emms instead of fninit to preserve FPU control word
-		emms
+		CLEAR_FPU_STACK
 
 		// Copy arguments from script
 		// stack to application stack
@@ -281,7 +302,7 @@ endcopy:
 	UNUSED_VAR(func);
 
 	asm("pushl %ecx           \n"
-		"emms                 \n"
+		_S(CLEAR_FPU_STACK)  "\n"
 
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
@@ -329,8 +350,7 @@ void NOINLINE CallCDeclFunctionObjLast(const void *obj, const asDWORD *args, int
 		push ecx
 
 		// Clear the FPU stack, in case the called function doesn't do it by itself
-		// Use emms instead of fninit to preserve FPU control word
-		emms
+		CLEAR_FPU_STACK
 
 		// Push the object pointer as the last argument to the function
 		push obj
@@ -370,7 +390,7 @@ endcopy:
 	UNUSED_VAR(func);
 
 	asm("pushl %ecx           \n"
-		"emms                 \n"
+		_S(CLEAR_FPU_STACK)  "\n"
 
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
@@ -420,8 +440,7 @@ void NOINLINE CallCDeclFunctionObjFirst(const void *obj, const asDWORD *args, in
 		push ecx
 
 		// Clear the FPU stack, in case the called function doesn't do it by itself
-		// Use emms instead of fninit to preserve FPU control word
-		emms
+		CLEAR_FPU_STACK
 
 		// Copy arguments from script
 		// stack to application stack
@@ -461,7 +480,7 @@ endcopy:
 	UNUSED_VAR(func);
 
 	asm("pushl %ecx           \n"
-		"emms                 \n"
+		_S(CLEAR_FPU_STACK)  "\n"
 
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
@@ -511,8 +530,7 @@ void NOINLINE CallCDeclFunctionRetByRefObjFirst_impl(const void *obj, const asDW
 		push ecx
 
 		// Clear the FPU stack, in case the called function doesn't do it by itself
-		// Use emms instead of fninit to preserve FPU control word
-		emms
+		CLEAR_FPU_STACK
 
 		// Copy arguments from script
 		// stack to application stack
@@ -561,7 +579,7 @@ endcopy:
 	UNUSED_VAR(retPtr);
 
 	asm("pushl %ecx           \n"
-		"emms                 \n"
+		_S(CLEAR_FPU_STACK)  "\n"
 
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
@@ -615,8 +633,7 @@ void NOINLINE CallCDeclFunctionRetByRef_impl(const asDWORD *args, int paramSize,
 		push ecx
 
 		// Clear the FPU stack, in case the called function doesn't do it by itself
-		// Use emms instead of fninit to preserve FPU control word
-		emms
+		CLEAR_FPU_STACK
 
 		// Copy arguments from script
 		// stack to application stack
@@ -659,7 +676,7 @@ endcopy:
 	UNUSED_VAR(retPtr);
 
 	asm("pushl %ecx           \n"
-		"emms                 \n"
+		_S(CLEAR_FPU_STACK)  "\n"
 
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
@@ -710,8 +727,7 @@ void NOINLINE CallCDeclFunctionRetByRefObjLast_impl(const void *obj, const asDWO
 		push ecx
 
 		// Clear the FPU stack, in case the called function doesn't do it by itself
-		// Use emms instead of fninit to preserve FPU control word
-		emms
+		CLEAR_FPU_STACK
 
 		push obj
 
@@ -758,7 +774,7 @@ endcopy:
 	UNUSED_VAR(retPtr);
 
 	asm("pushl %ecx           \n"
-		"emms                 \n"
+		_S(CLEAR_FPU_STACK)  "\n"
 
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
@@ -812,8 +828,7 @@ void NOINLINE CallSTDCallFunction(const asDWORD *args, int paramSize, size_t fun
 		push ecx
 
 		// Clear the FPU stack, in case the called function doesn't do it by itself
-		// Use emms instead of fninit to preserve FPU control word
-		emms
+		CLEAR_FPU_STACK
 
 		// Copy arguments from script
 		// stack to application stack
@@ -847,7 +862,7 @@ endcopy:
 	UNUSED_VAR(func);
 
 	asm("pushl %ecx           \n"
-		"emms                 \n"
+		_S(CLEAR_FPU_STACK)  "\n"
 
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
@@ -895,8 +910,7 @@ void NOINLINE CallThisCallFunction(const void *obj, const asDWORD *args, int par
 		push ecx
 
 		// Clear the FPU stack, in case the called function doesn't do it by itself
-		// Use emms instead of fninit to preserve FPU control word
-		emms
+		CLEAR_FPU_STACK
 
 		// Copy arguments from script
 		// stack to application stack
@@ -946,7 +960,7 @@ endcopy:
 	UNUSED_VAR(func);
 
 	asm("pushl %ecx           \n"
-		"emms                 \n"
+		_S(CLEAR_FPU_STACK)  "\n"
 
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need
@@ -997,8 +1011,7 @@ void NOINLINE CallThisCallFunctionRetByRef_impl(const void *obj, const asDWORD *
 		push ecx
 
 		// Clear the FPU stack, in case the called function doesn't do it by itself
-		// Use emms instead of fninit to preserve FPU control word
-		emms
+		CLEAR_FPU_STACK
 
 		// Copy arguments from script
 		// stack to application stack
@@ -1057,7 +1070,7 @@ endcopy:
 	UNUSED_VAR(retPtr);
 
 	asm("pushl %ecx           \n"
-		"emms                 \n"
+		_S(CLEAR_FPU_STACK)  "\n"
 
 		// Need to align the stack pointer so that it is aligned to 16 bytes when making the function call.
 		// It is assumed that when entering this function, the stack pointer is already aligned, so we need