Stabilize core Mojo ABI

Removes the last dubious API surface (size_t usage) in the core ABI and
documents the ABI as stable.

Bug: 822034,819046
Change-Id: I60438dd6613d45738514a92ce8c21777b859bfee
Reviewed-on: https://chromium-review.googlesource.com/1062932
Reviewed-by: Jay Civelli <jcivelli@chromium.org>
Commit-Queue: Ken Rockot <rockot@chromium.org>
Cr-Commit-Position: refs/heads/master@{#559348}

CrOS-Libchrome-Original-Commit: 1da30cab1d95b4d161e3ab570de0ed413fa97af0
diff --git a/mojo/edk/embedder/entrypoints.cc b/mojo/edk/embedder/entrypoints.cc
index 08313cc..11dcde5 100644
--- a/mojo/edk/embedder/entrypoints.cc
+++ b/mojo/edk/embedder/entrypoints.cc
@@ -122,7 +122,7 @@
 MojoResult MojoNotifyBadMessageImpl(
     MojoMessageHandle message,
     const char* error,
-    size_t error_num_bytes,
+    uint32_t error_num_bytes,
     const MojoNotifyBadMessageOptions* options) {
   return g_core->NotifyBadMessage(message, error, error_num_bytes, options);
 }
diff --git a/mojo/edk/system/multiprocess_message_pipe_unittest.cc b/mojo/edk/system/multiprocess_message_pipe_unittest.cc
index 162f29a..211d7cb 100644
--- a/mojo/edk/system/multiprocess_message_pipe_unittest.cc
+++ b/mojo/edk/system/multiprocess_message_pipe_unittest.cc
@@ -1373,16 +1373,19 @@
       MojoMessageHandle message;
       ASSERT_EQ(MOJO_RESULT_OK, ::MojoReadMessage(a, nullptr, &message));
       EXPECT_EQ(MOJO_RESULT_OK,
-                MojoNotifyBadMessage(message, kFirstErrorMessage.data(),
-                                     kFirstErrorMessage.size(), nullptr));
+                MojoNotifyBadMessage(
+                    message, kFirstErrorMessage.data(),
+                    static_cast<uint32_t>(kFirstErrorMessage.size()), nullptr));
       EXPECT_EQ(MOJO_RESULT_OK, MojoDestroyMessage(message));
 
       // Read a message from the pipe we sent to child2 and flag it as bad.
       ASSERT_EQ(MOJO_RESULT_OK, WaitForSignals(c, MOJO_HANDLE_SIGNAL_READABLE));
       ASSERT_EQ(MOJO_RESULT_OK, ::MojoReadMessage(c, nullptr, &message));
-      EXPECT_EQ(MOJO_RESULT_OK,
-                MojoNotifyBadMessage(message, kSecondErrorMessage.data(),
-                                     kSecondErrorMessage.size(), nullptr));
+      EXPECT_EQ(
+          MOJO_RESULT_OK,
+          MojoNotifyBadMessage(
+              message, kSecondErrorMessage.data(),
+              static_cast<uint32_t>(kSecondErrorMessage.size()), nullptr));
       EXPECT_EQ(MOJO_RESULT_OK, MojoDestroyMessage(message));
 
       WriteMessage(child2, "bye");
diff --git a/mojo/public/c/system/message_pipe.h b/mojo/public/c/system/message_pipe.h
index d92e7b4..9f222f9 100644
--- a/mojo/public/c/system/message_pipe.h
+++ b/mojo/public/c/system/message_pipe.h
@@ -591,7 +591,7 @@
 MOJO_SYSTEM_EXPORT MojoResult
 MojoNotifyBadMessage(MojoMessageHandle message,
                      const char* error,
-                     size_t error_num_bytes,
+                     uint32_t error_num_bytes,
                      const struct MojoNotifyBadMessageOptions* options);
 
 #ifdef __cplusplus
diff --git a/mojo/public/c/system/thunks.cc b/mojo/public/c/system/thunks.cc
index 2f67536..a1be5de 100644
--- a/mojo/public/c/system/thunks.cc
+++ b/mojo/public/c/system/thunks.cc
@@ -307,7 +307,7 @@
 
 MojoResult MojoNotifyBadMessage(MojoMessageHandle message,
                                 const char* error,
-                                size_t error_num_bytes,
+                                uint32_t error_num_bytes,
                                 const MojoNotifyBadMessageOptions* options) {
   return g_thunks.NotifyBadMessage(message, error, error_num_bytes, options);
 }
diff --git a/mojo/public/c/system/thunks.h b/mojo/public/c/system/thunks.h
index e205b02..97d5636 100644
--- a/mojo/public/c/system/thunks.h
+++ b/mojo/public/c/system/thunks.h
@@ -13,13 +13,24 @@
 #include "mojo/public/c/system/core.h"
 #include "mojo/public/c/system/system_export.h"
 
-// Structure used to bind the basic Mojo Core functions to an embedder
-// implementation. This is intended to eventually be used as a stable ABI
-// between a Mojo embedder and some loaded application code, but for now it is
-// still effectively safe to rearrange entries as needed.
+// This defines the *stable*, foward-compatible ABI for the Mojo Core C library.
+// As such, the following types of changes are DISALLOWED:
+//
+//   - DO NOT delete or re-order any of the fields in this structure
+//   - DO NOT modify any function signatures defined here
+//   - DO NOT alter the alignment of the stucture
+//
+// Some changes are of course permissible:
+//
+//   - DO feel free to rename existing fields if there's a good reason to do so,
+//     e.g. deprecation of a function for all future applications.
+//   - DO add new functions to the end of this structure, but ensure that they
+//     have a signature which lends itself to reasonably extensible behavior
+//     (e.g. an optional "Options" structure as many functions here have).
+//
 #pragma pack(push, 8)
 struct MojoSystemThunks {
-  size_t size;  // Should be set to sizeof(MojoSystemThunks).
+  uint32_t size;  // Should be set to sizeof(MojoSystemThunks).
 
   MojoResult (*Initialize)(const struct MojoInitializeOptions* options);
 
@@ -81,7 +92,7 @@
   MojoResult (*NotifyBadMessage)(
       MojoMessageHandle message,
       const char* error,
-      size_t error_num_bytes,
+      uint32_t error_num_bytes,
       const struct MojoNotifyBadMessageOptions* options);
 
   // Data pipe API.
diff --git a/mojo/public/cpp/system/message.h b/mojo/public/cpp/system/message.h
index 3234eae..127ff18 100644
--- a/mojo/public/cpp/system/message.h
+++ b/mojo/public/cpp/system/message.h
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "base/macros.h"
+#include "base/numerics/safe_conversions.h"
 #include "base/strings/string_piece.h"
 #include "mojo/public/c/system/message_pipe.h"
 #include "mojo/public/cpp/system/handle.h"
@@ -90,8 +91,9 @@
 inline MojoResult NotifyBadMessage(MessageHandle message,
                                    const base::StringPiece& error) {
   DCHECK(message.is_valid());
-  return MojoNotifyBadMessage(message.value(), error.data(), error.size(),
-                              nullptr);
+  DCHECK(base::IsValueInRangeForNumericType<uint32_t>(error.size()));
+  return MojoNotifyBadMessage(message.value(), error.data(),
+                              static_cast<uint32_t>(error.size()), nullptr);
 }
 
 }  // namespace mojo