Add the ability to Release typed arrays

This unpins the memory and lets the client do other operations that could
trigger GC.

Change-Id: I2a71feb2fefe5feb016a9ca775e6d04ed9d591d5
diff --git a/typed_data/float32_list.cc b/typed_data/float32_list.cc
index 425c7d3..6ce10d2 100644
--- a/typed_data/float32_list.cc
+++ b/typed_data/float32_list.cc
@@ -32,8 +32,16 @@
 }
 
 Float32List::~Float32List() {
-  if (data_)
+  Release();
+}
+
+void Float32List::Release() {
+  if (data_) {
     Dart_TypedDataReleaseData(dart_handle_);
+    data_ = nullptr;
+    num_elements_ = 0;
+    dart_handle_ = nullptr;
+  }
 }
 
 Float32List DartConverter<Float32List>::FromArguments(Dart_NativeArguments args,
diff --git a/typed_data/float32_list.h b/typed_data/float32_list.h
index 512a8ae..8fb6316 100644
--- a/typed_data/float32_list.h
+++ b/typed_data/float32_list.h
@@ -38,6 +38,8 @@
   intptr_t num_elements() const { return num_elements_; }
   Dart_Handle dart_handle() const { return dart_handle_; }
 
+  void Release();
+
  private:
   float* data_;
   intptr_t num_elements_;
diff --git a/typed_data/float64_list.cc b/typed_data/float64_list.cc
index 50f6760..b2747d9 100644
--- a/typed_data/float64_list.cc
+++ b/typed_data/float64_list.cc
@@ -32,8 +32,16 @@
 }
 
 Float64List::~Float64List() {
-  if (data_)
+  Release();
+}
+
+void Float64List::Release() {
+  if (data_) {
     Dart_TypedDataReleaseData(dart_handle_);
+    data_ = nullptr;
+    num_elements_ = 0;
+    dart_handle_ = nullptr;
+  }
 }
 
 Float64List DartConverter<Float64List>::FromArguments(Dart_NativeArguments args,
diff --git a/typed_data/float64_list.h b/typed_data/float64_list.h
index 090c54e..81f9fce 100644
--- a/typed_data/float64_list.h
+++ b/typed_data/float64_list.h
@@ -38,6 +38,8 @@
   intptr_t num_elements() const { return num_elements_; }
   Dart_Handle dart_handle() const { return dart_handle_; }
 
+  void Release();
+
  private:
   double* data_;
   intptr_t num_elements_;
diff --git a/typed_data/int32_list.cc b/typed_data/int32_list.cc
index 534dca8..76e1b8c 100644
--- a/typed_data/int32_list.cc
+++ b/typed_data/int32_list.cc
@@ -39,6 +39,8 @@
   if (data_) {
     Dart_TypedDataReleaseData(dart_handle_);
     data_ = nullptr;
+    num_elements_ = 0;
+    dart_handle_ = nullptr;
   }
 }
 
diff --git a/typed_data/uint8_list.cc b/typed_data/uint8_list.cc
index b8f4b14..6e1ba9f 100644
--- a/typed_data/uint8_list.cc
+++ b/typed_data/uint8_list.cc
@@ -34,8 +34,16 @@
 }
 
 Uint8List::~Uint8List() {
-  if (data_)
+  Release();
+}
+
+void Uint8List::Release() {
+  if (data_) {
     Dart_TypedDataReleaseData(dart_handle_);
+    data_ = nullptr;
+    num_elements_ = 0;
+    dart_handle_ = nullptr;
+  }
 }
 
 Uint8List DartConverter<Uint8List>::FromArguments(Dart_NativeArguments args,
diff --git a/typed_data/uint8_list.h b/typed_data/uint8_list.h
index cf5a85a..78aa54d 100644
--- a/typed_data/uint8_list.h
+++ b/typed_data/uint8_list.h
@@ -38,6 +38,8 @@
   intptr_t num_elements() const { return num_elements_; }
   Dart_Handle dart_handle() const { return dart_handle_; }
 
+  void Release();
+
  private:
   uint8_t* data_;
   intptr_t num_elements_;