[orc-rt] Enable transparent SPS conversion for Expected<T*>. (#162073)

Expected<T*> values will be converted to/from Expected<ExecutorAddr>
values.
diff --git a/orc-rt/include/orc-rt/SPSWrapperFunction.h b/orc-rt/include/orc-rt/SPSWrapperFunction.h
index e5ed14f..5cf3873 100644
--- a/orc-rt/include/orc-rt/SPSWrapperFunction.h
+++ b/orc-rt/include/orc-rt/SPSWrapperFunction.h
@@ -63,6 +63,21 @@
     }
   };
 
+  template <typename T> struct Serializable<Expected<T *>> {
+    typedef SPSSerializableExpected<ExecutorAddr> serializable_type;
+    static SPSSerializableExpected<ExecutorAddr> to(Expected<T *> Val) {
+      return SPSSerializableExpected<ExecutorAddr>(
+          Val ? Expected<ExecutorAddr>(ExecutorAddr::fromPtr(*Val))
+              : Expected<ExecutorAddr>(Val.takeError()));
+    }
+    static Expected<T *> from(SPSSerializableExpected<ExecutorAddr> Val) {
+      if (auto Tmp = Val.toExpected())
+        return Tmp->toPtr<T *>();
+      else
+        return Tmp.takeError();
+    }
+  };
+
   template <typename... Ts> struct DeserializableTuple;
 
   template <typename... Ts> struct DeserializableTuple<std::tuple<Ts...>> {
diff --git a/orc-rt/unittests/SPSWrapperFunctionTest.cpp b/orc-rt/unittests/SPSWrapperFunctionTest.cpp
index 7f88ce0..9d0d9e4 100644
--- a/orc-rt/unittests/SPSWrapperFunctionTest.cpp
+++ b/orc-rt/unittests/SPSWrapperFunctionTest.cpp
@@ -242,6 +242,30 @@
   EXPECT_EQ(P, &X);
 }
 
+static void
+expected_int_pointer_sps_wrapper(orc_rt_SessionRef Session, void *CallCtx,
+                                 orc_rt_WrapperFunctionReturn Return,
+                                 orc_rt_WrapperFunctionBuffer ArgBytes) {
+  SPSWrapperFunction<SPSExpected<SPSExecutorAddr>(SPSExecutorAddr)>::handle(
+      Session, CallCtx, Return, ArgBytes,
+      [](move_only_function<void(Expected<int32_t *>)> Return, int32_t *P) {
+        Return(P);
+      });
+}
+
+TEST(SPSWrapperFunctionUtilsTest, TransparentSerializationExpectedPointers) {
+  int X = 42;
+  int *P = nullptr;
+  SPSWrapperFunction<SPSExpected<SPSExecutorAddr>(SPSExecutorAddr)>::call(
+      DirectCaller(nullptr, expected_int_pointer_sps_wrapper),
+      [&](Expected<Expected<int32_t *>> R) {
+        P = cantFail(cantFail(std::move(R)));
+      },
+      &X);
+
+  EXPECT_EQ(P, &X);
+}
+
 template <size_t N> struct SPSOpCounter {};
 
 namespace orc_rt {