[vm, isolate] Fix length truncation in message snapshots.

Bug: https://github.com/dart-lang/sdk/issues/35635
Change-Id: I942f2c98c300d72e4b36329ab2e2d0d51029f478
Reviewed-on: https://dart-review.googlesource.com/c/89168
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 5a4d2f5..ea491de 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -187,9 +187,9 @@
 }
 
 RawSmi* BaseReader::ReadAsSmi() {
-  intptr_t value = Read<int32_t>();
-  ASSERT((value & kSmiTagMask) == kSmiTag);
-  return reinterpret_cast<RawSmi*>(value);
+  RawSmi* value = Read<RawSmi*>();
+  ASSERT((reinterpret_cast<uword>(value) & kSmiTagMask) == kSmiTag);
+  return value;
 }
 
 intptr_t BaseReader::ReadSmiValue() {
diff --git a/tests/lib_2/isolate/int32_length_overflow_test.dart b/tests/lib_2/isolate/int32_length_overflow_test.dart
new file mode 100644
index 0000000..2e3806c
--- /dev/null
+++ b/tests/lib_2/isolate/int32_length_overflow_test.dart
@@ -0,0 +1,99 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+import "dart:isolate";
+import "dart:typed_data";
+import "package:expect/expect.dart";
+
+const large = 1 << 30;
+
+void child(replyPort) {
+  print("Child start");
+
+  print("Child Uint8List");
+  dynamic x = new Uint8List(large);
+  for (int i = 0; i < 4; i++) {
+    x[i] = i;
+  }
+  for (int i = x.length - 4; i < x.length; i++) {
+    x[i] = x.length - i;
+  }
+  replyPort.send(x);
+  x = null;
+
+  // Too slow.
+  // print("Child Array");
+  // x = new List(large);
+  // for (int i = 0; i < 4; i++) {
+  //   x[i] = i;
+  // }
+  // replyPort.send(x);
+  // x = null;
+
+  print("Child OneByteString");
+  x = null;
+  x = "Z";
+  while (x.length < large) {
+    x = x * 2;
+  }
+  replyPort.send(x);
+  x = null;
+
+  print("Child done");
+}
+
+Future<void> main(List<String> args) async {
+  try {
+    new List(large);
+  } on OutOfMemoryError catch (e) {
+    return; // 32-bit hosts cannot allocate objects large enough for this test.
+  }
+
+  print("Parent start");
+
+  ReceivePort port = new ReceivePort();
+  Isolate.spawn(child, port.sendPort);
+  StreamIterator<dynamic> incoming = new StreamIterator<dynamic>(port);
+
+  print("Parent Uint8");
+  Expect.isTrue(await incoming.moveNext());
+  dynamic x = incoming.current;
+  Expect.isTrue(x is Uint8List);
+  Expect.equals(large, x.length);
+  for (int i = 0; i < 4; i++) {
+    Expect.equals(i, x[i]);
+  }
+  for (int i = x.length - 4; i < x.length; i++) {
+    Expect.equals(x.length - i, x[i]);
+  }
+  x = null;
+
+  // Too slow.
+  // print("Parent Array");
+  // Expect.isTrue(await incoming.moveNext());
+  // x = incoming.current;
+  // Expect.isTrue(x is List);
+  // Expect.equals(large, x.length);
+  // for (int i = 0; i < 4; i++) {
+  //   Expect.equals(i, x[i]);
+  // }
+  // x = null;
+
+  print("Parent OneByteString");
+  Expect.isTrue(await incoming.moveNext());
+  x = incoming.current;
+  Expect.isTrue(x is String);
+  Expect.equals(large, x.length);
+  for (int i = 0; i < 4; i++) {
+    Expect.equals("Z", x[i]);
+  }
+  for (int i = x.length - 4; i < x.length; i++) {
+    Expect.equals("Z", x[i]);
+  }
+  x = null;
+
+  port.close();
+  print("Parent done");
+}
diff --git a/tests/lib_2/lib_2.status b/tests/lib_2/lib_2.status
index dc0745a..3efad9d 100644
--- a/tests/lib_2/lib_2.status
+++ b/tests/lib_2/lib_2.status
@@ -238,6 +238,7 @@
 
 [ $runtime == dart_precompiled || $runtime == flutter || $runtime == vm ]
 isolate/browser/*: SkipByDesign # Browser specific tests
+isolate/int32_length_overflow_test.dart: Pass, Slow
 isolate/isolate_stress_test: Skip # Issue 12588: Uses dart:html. This should be able to pass when we have wrapper-less tests.
 isolate/stacktrace_message_test: RuntimeError # Fails to send stacktrace object.