Reactor: Add ConstantData() and member function calling

rr::ConstantData() returns a Pointer<Byte> to an immutable copy of the provided data.

Added two new variants of rr::Call() for calling member function pointers.

Added tests.

Bug: b/143479561
Change-Id: I5846fb313fbd81821bf4e9bb655414a5e0eaf133
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/38408
Tested-by: Ben Clayton <bclayton@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index e070dd3..17740a4 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -53,6 +53,11 @@
 #include <limits>
 #include <iostream>
 
+namespace rr
+{
+	class ELFMemoryStreamer;
+}
+
 namespace
 {
 	// Default configuration settings. Must be accessed under mutex lock.
@@ -71,7 +76,7 @@
 	Ice::Cfg *function = nullptr;
 	Ice::CfgNode *basicBlock = nullptr;
 	Ice::CfgLocalAllocatorScope *allocator = nullptr;
-	rr::Routine *routine = nullptr;
+	rr::ELFMemoryStreamer *routine = nullptr;
 
 	std::mutex codegenMutex;
 
@@ -543,10 +548,20 @@
 			return entry;
 		}
 
+		const void* addConstantData(const void* data, size_t size)
+		{
+			auto buf = std::unique_ptr<uint8_t[]>(new uint8_t[size]);
+			memcpy(buf.get(), data, size);
+			auto ptr = buf.get();
+			constantData.emplace_back(std::move(buf));
+			return ptr;
+		}
+
 	private:
 		void *entry;
 		std::vector<uint8_t, ExecutableAllocator<uint8_t>> buffer;
 		std::size_t position;
+		std::vector<std::unique_ptr<uint8_t[]>> constantData;
 
 		#if defined(_WIN32)
 		DWORD oldProtection;
@@ -3497,6 +3512,13 @@
 		}
 	}
 
+	RValue<Pointer<Byte>> ConstantData(void const * data, size_t size)
+	{
+		// TODO: Try to use Ice::VariableDeclaration::DataInitializer and
+		// getConstantSym instead of tagging data on the routine.
+		return ConstantPointer(::routine->addConstantData(data, size));
+	}
+
 	Value* Call(RValue<Pointer<Byte>> fptr, Type* retTy, std::initializer_list<Value*> args, std::initializer_list<Type*> argTys)
 	{
 		// FIXME: This does not currently work on Windows.