From 5d9784f215d20026d82c333e7f5c981a6c604072 Mon Sep 17 00:00:00 2001
From: Magnus Norddahl <dpjudas@users.noreply.github.com>
Date: Mon, 3 Dec 2018 21:58:01 +0100
Subject: [PATCH] - fix VM native calls containing strings and enable them
 again

---
 src/scripting/vm/jit_call.cpp | 59 ++++++++++++++++++++---------------
 src/scripting/vm/vm.h         |  2 +-
 2 files changed, 35 insertions(+), 26 deletions(-)

diff --git a/src/scripting/vm/jit_call.cpp b/src/scripting/vm/jit_call.cpp
index 0f8f85e826..2c9694e4e2 100644
--- a/src/scripting/vm/jit_call.cpp
+++ b/src/scripting/vm/jit_call.cpp
@@ -360,13 +360,17 @@ void JitCompiler::EmitNativeCall(VMNativeFunction *target)
 				call->setArg(slot, regS[bc]);
 				break;
 			case REGT_STRING | REGT_KONST:
-				call->setArg(slot, imm_ptr(&konsts[bc]));
+				tmp = newTempIntPtr();
+				cc.mov(tmp, imm_ptr(&konsts[bc]));
+				call->setArg(slot, tmp);
 				break;
 			case REGT_POINTER:
 				call->setArg(slot, regA[bc]);
 				break;
 			case REGT_POINTER | REGT_KONST:
-				call->setArg(slot, asmjit::imm_ptr(konsta[bc].v));
+				tmp = newTempIntPtr();
+				cc.mov(tmp, imm_ptr(konsta[bc].v));
+				call->setArg(slot, tmp);
 				break;
 			case REGT_FLOAT:
 				call->setArg(slot, regF[bc]);
@@ -442,28 +446,36 @@ void JitCompiler::EmitNativeCall(VMNativeFunction *target)
 
 		CheckVMFrame();
 
-		auto regPtr = newTempIntPtr();
-
-		switch (type & REGT_TYPE)
+		if ((type & REGT_TYPE) == REGT_STRING)
 		{
-		case REGT_INT:
-			cc.lea(regPtr, x86::ptr(vmframe, offsetD + (int)(regnum * sizeof(int32_t))));
-			break;
-		case REGT_FLOAT:
-			cc.lea(regPtr, x86::ptr(vmframe, offsetF + (int)(regnum * sizeof(double))));
-			break;
-		case REGT_STRING:
-			cc.lea(regPtr, x86::ptr(vmframe, offsetS + (int)(regnum * sizeof(FString))));
-			break;
-		case REGT_POINTER:
-			cc.lea(regPtr, x86::ptr(vmframe, offsetA + (int)(regnum * sizeof(void*))));
-			break;
-		default:
-			I_FatalError("Unknown OP_RESULT type encountered\n");
-			break;
+			// For strings we already have them on the stack and got named registers for them.
+			call->setArg(numparams + i - startret, regS[regnum]);
 		}
+		else
+		{
+			auto regPtr = newTempIntPtr();
 
-		call->setArg(numparams + i - startret, regPtr);
+			switch (type & REGT_TYPE)
+			{
+			case REGT_INT:
+				cc.lea(regPtr, x86::ptr(vmframe, offsetD + (int)(regnum * sizeof(int32_t))));
+				break;
+			case REGT_FLOAT:
+				cc.lea(regPtr, x86::ptr(vmframe, offsetF + (int)(regnum * sizeof(double))));
+				break;
+			case REGT_STRING:
+				cc.lea(regPtr, x86::ptr(vmframe, offsetS + (int)(regnum * sizeof(FString))));
+				break;
+			case REGT_POINTER:
+				cc.lea(regPtr, x86::ptr(vmframe, offsetA + (int)(regnum * sizeof(void*))));
+				break;
+			default:
+				I_FatalError("Unknown OP_RESULT type encountered\n");
+				break;
+			}
+
+			call->setArg(numparams + i - startret, regPtr);
+		}
 	}
 
 	cc.setCursor(cursorAfter);
@@ -621,14 +633,11 @@ asmjit::FuncSignature JitCompiler::CreateFuncSignature()
 			rettype = TypeIdOf<double>::kTypeId;
 			key += "rf";
 			break;
-		case REGT_STRING:
-			rettype = TypeIdOf<void*>::kTypeId;
-			key += "rs";
-			break;
 		case REGT_POINTER:
 			rettype = TypeIdOf<void*>::kTypeId;
 			key += "rv";
 			break;
+		case REGT_STRING:
 		default:
 			startret = 0;
 			break;
diff --git a/src/scripting/vm/vm.h b/src/scripting/vm/vm.h
index 80f97b7938..98c59eb67a 100644
--- a/src/scripting/vm/vm.h
+++ b/src/scripting/vm/vm.h
@@ -591,7 +591,7 @@ struct AFuncDesc
 #define DEFINE_ACTION_FUNCTION_NATIVE(cls, name, native) \
 	static int AF_##cls##_##name(VM_ARGS); \
 	VMNativeFunction *cls##_##name##_VMPtr; \
-	static const AFuncDesc cls##_##name##_Hook = { #cls, #name, AF_##cls##_##name, &cls##_##name##_VMPtr, nullptr/* reinterpret_cast<void*>(native)*/ }; \
+	static const AFuncDesc cls##_##name##_Hook = { #cls, #name, AF_##cls##_##name, &cls##_##name##_VMPtr, reinterpret_cast<void*>(native) }; \
 	extern AFuncDesc const *const cls##_##name##_HookPtr; \
 	MSVC_ASEG AFuncDesc const *const cls##_##name##_HookPtr GCC_ASEG = &cls##_##name##_Hook; \
 	static int AF_##cls##_##name(VM_ARGS)