[vm] Use std::unique_ptr for kernel::Program

Updates #37244.

Change-Id: I994298162966eca9cf5217cad2ae0aae4f438b4c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/106950
Reviewed-by: RĂ©gis Crelier <regis@google.com>
Commit-Queue: Matthew Dempsky <mdempsky@google.com>
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 1b38ff7..9c68200 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -79,7 +79,7 @@
                                      intptr_t kernel_buffer_size) {
   Zone* zone = thread->zone();
   const char* error = nullptr;
-  kernel::Program* program = kernel::Program::ReadFromBuffer(
+  std::unique_ptr<kernel::Program> program = kernel::Program::ReadFromBuffer(
       kernel_buffer, kernel_buffer_size, &error);
   if (program == nullptr) {
     const intptr_t kMessageBufferSize = 512;
@@ -89,7 +89,7 @@
     const String& msg = String::Handle(String::New(message_buffer, Heap::kOld));
     return ApiError::New(msg, Heap::kOld);
   }
-  kernel::KernelLoader loader(program, /*uri_to_source_table=*/nullptr);
+  kernel::KernelLoader loader(program.get(), /*uri_to_source_table=*/nullptr);
 
   Isolate* isolate = thread->isolate();
 
@@ -111,7 +111,7 @@
   // The platform binary may contain other libraries (e.g., dart:_builtin or
   // dart:io) that will not be bundled with application.  Load them now.
   const Object& result = Object::Handle(zone, loader.LoadProgram());
-  delete program;
+  program.reset();
   if (result.IsError()) {
     return Error::Cast(result).raw();
   }
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index ee31194..5e84bd0 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -5042,13 +5042,13 @@
   BumpAllocateScope bump_allocate_scope(T);
 
   const char* error = nullptr;
-  kernel::Program* program =
+  std::unique_ptr<kernel::Program> program =
       kernel::Program::ReadFromBuffer(buffer, buffer_size, &error);
   if (program == nullptr) {
     return Api::NewError("Can't load Kernel binary: %s.", error);
   }
-  const Object& tmp = kernel::KernelLoader::LoadEntireProgram(program);
-  delete program;
+  const Object& tmp = kernel::KernelLoader::LoadEntireProgram(program.get());
+  program.reset();
 
   if (tmp.IsError()) {
     return Api::NewHandle(T, tmp.raw());
@@ -5288,14 +5288,14 @@
   BumpAllocateScope bump_allocate_scope(T);
 
   const char* error = nullptr;
-  kernel::Program* program =
+  std::unique_ptr<kernel::Program> program =
       kernel::Program::ReadFromBuffer(buffer, buffer_size, &error);
   if (program == nullptr) {
     return Api::NewError("Can't load Kernel binary: %s.", error);
   }
   const Object& result =
-      kernel::KernelLoader::LoadEntireProgram(program, false);
-  delete program;
+      kernel::KernelLoader::LoadEntireProgram(program.get(), false);
+  program.reset();
 
   return Api::NewHandle(T, result.raw());
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index 75273e8..eb4aacb 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -526,17 +526,6 @@
   return (a_length - a_cursor);
 }
 
-template <class T>
-class ResourceHolder : ValueObject {
-  T* resource_;
-
- public:
-  ResourceHolder() : resource_(NULL) {}
-  void set(T* resource) { resource_ = resource; }
-  T* get() { return resource_; }
-  ~ResourceHolder() { delete (resource_); }
-};
-
 static void AcceptCompilation(Thread* thread) {
   TransitionVMToNative transition(thread);
   Dart_KernelCompilationResult result = KernelIsolate::AcceptCompilation();
@@ -582,7 +571,7 @@
   }
 
   Object& result = Object::Handle(thread->zone());
-  ResourceHolder<kernel::Program> kernel_program;
+  std::unique_ptr<kernel::Program> kernel_program;
   String& packages_url = String::Handle();
   if (packages_url_ != NULL) {
     packages_url = String::New(packages_url_);
@@ -609,10 +598,10 @@
     // root_script_url is a valid .dill file. If that's the case, a Program*
     // is returned. Otherwise, this is likely a source file that needs to be
     // compiled, so ReadKernelFromFile returns NULL.
-    kernel_program.set(kernel::Program::ReadFromFile(root_script_url));
-    if (kernel_program.get() != NULL) {
-      num_received_libs_ = kernel_program.get()->library_count();
-      bytes_received_libs_ = kernel_program.get()->kernel_data_size();
+    kernel_program = kernel::Program::ReadFromFile(root_script_url);
+    if (kernel_program != nullptr) {
+      num_received_libs_ = kernel_program->library_count();
+      bytes_received_libs_ = kernel_program->kernel_data_size();
       p_num_received_classes = &num_received_classes_;
       p_num_received_procedures = &num_received_procedures_;
     } else {
@@ -669,7 +658,7 @@
       // into the middle of c-allocated buffer and don't have a finalizer).
       I->RetainKernelBlob(typed_data);
 
-      kernel_program.set(kernel::Program::ReadFromTypedData(typed_data));
+      kernel_program = kernel::Program::ReadFromTypedData(typed_data);
     }
 
     kernel::KernelLoader::FindModifiedLibraries(
diff --git a/runtime/vm/kernel.h b/runtime/vm/kernel.h
index 32f975f..9afdc32 100644
--- a/runtime/vm/kernel.h
+++ b/runtime/vm/kernel.h
@@ -5,6 +5,8 @@
 #ifndef RUNTIME_VM_KERNEL_H_
 #define RUNTIME_VM_KERNEL_H_
 
+#include <memory>
+
 #include "platform/assert.h"
 #include "vm/allocation.h"
 #include "vm/globals.h"
@@ -62,15 +64,16 @@
   // Read a kernel Program from the given Reader. Note the returned Program
   // can potentially contain several "sub programs", though the library count
   // etc will reference the last "sub program" only.
-  static Program* ReadFrom(Reader* reader, const char** error = nullptr);
+  static std::unique_ptr<Program> ReadFrom(Reader* reader,
+                                           const char** error = nullptr);
 
-  static Program* ReadFromFile(const char* script_uri,
-                               const char** error = nullptr);
-  static Program* ReadFromBuffer(const uint8_t* buffer,
-                                 intptr_t buffer_length,
-                                 const char** error = nullptr);
-  static Program* ReadFromTypedData(const ExternalTypedData& typed_data,
-                                    const char** error = nullptr);
+  static std::unique_ptr<Program> ReadFromFile(const char* script_uri,
+                                               const char** error = nullptr);
+  static std::unique_ptr<Program> ReadFromBuffer(const uint8_t* buffer,
+                                                 intptr_t buffer_length,
+                                                 const char** error = nullptr);
+  static std::unique_ptr<Program> ReadFromTypedData(
+      const ExternalTypedData& typed_data, const char** error = nullptr);
 
   bool is_single_program() { return single_program_; }
   uint32_t binary_version() { return binary_version_; }
diff --git a/runtime/vm/kernel_binary.cc b/runtime/vm/kernel_binary.cc
index d974b31..eda3858 100644
--- a/runtime/vm/kernel_binary.cc
+++ b/runtime/vm/kernel_binary.cc
@@ -81,7 +81,7 @@
 const char* kKernelInvalidSizeIndicated =
     "Invalid kernel binary: Indicated size is invalid";
 
-Program* Program::ReadFrom(Reader* reader, const char** error) {
+std::unique_ptr<Program> Program::ReadFrom(Reader* reader, const char** error) {
   if (reader->size() < 60) {
     // A kernel file currently contains at least the following:
     //   * Magic number (32)
@@ -120,7 +120,7 @@
     return nullptr;
   }
 
-  Program* program = new Program();
+  std::unique_ptr<Program> program(new Program());
   program->binary_version_ = formatVersion;
   program->kernel_data_ = reader->buffer();
   program->kernel_data_size_ = reader->size();
@@ -136,7 +136,6 @@
       if (error != nullptr) {
         *error = kKernelInvalidSizeIndicated;
       }
-      delete program;
       return nullptr;
     }
     ++subprogram_count;
@@ -164,13 +163,13 @@
   return program;
 }
 
-Program* Program::ReadFromFile(const char* script_uri,
-                               const char** error /* = nullptr */) {
+std::unique_ptr<Program> Program::ReadFromFile(
+    const char* script_uri, const char** error /* = nullptr */) {
   Thread* thread = Thread::Current();
   if (script_uri == NULL) {
-    return NULL;
+    return nullptr;
   }
-  kernel::Program* kernel_program = NULL;
+  std::unique_ptr<kernel::Program> kernel_program;
 
   const String& uri = String::Handle(String::New(script_uri));
   const Object& ret = Object::Handle(thread->isolate()->CallTagHandler(
@@ -204,15 +203,15 @@
   return kernel_program;
 }
 
-Program* Program::ReadFromBuffer(const uint8_t* buffer,
-                                 intptr_t buffer_length,
-                                 const char** error) {
+std::unique_ptr<Program> Program::ReadFromBuffer(const uint8_t* buffer,
+                                                 intptr_t buffer_length,
+                                                 const char** error) {
   kernel::Reader reader(buffer, buffer_length);
   return kernel::Program::ReadFrom(&reader, error);
 }
 
-Program* Program::ReadFromTypedData(const ExternalTypedData& typed_data,
-                                    const char** error) {
+std::unique_ptr<Program> Program::ReadFromTypedData(
+    const ExternalTypedData& typed_data, const char** error) {
   kernel::Reader reader(typed_data);
   return kernel::Program::ReadFrom(&reader, error);
 }
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index f7ce8e0..a6c0a27 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -294,17 +294,15 @@
     reader.set_raw_buffer(program->kernel_data() + subprogram_start);
     reader.set_size(subprogram_end - subprogram_start);
     reader.set_offset(0);
-    Program* subprogram = Program::ReadFrom(&reader);
+    std::unique_ptr<Program> subprogram = Program::ReadFrom(&reader);
     ASSERT(subprogram->is_single_program());
-    KernelLoader loader(subprogram, &uri_to_source_table);
+    KernelLoader loader(subprogram.get(), &uri_to_source_table);
     Object& load_result = Object::Handle(loader.LoadProgram(false));
     if (load_result.IsError()) return load_result;
 
     if (load_result.IsLibrary()) {
       library ^= load_result.raw();
     }
-
-    delete subprogram;
   }
 
   if (process_pending_classes && !ClassFinalizer::ProcessPendingClasses()) {
@@ -874,12 +872,11 @@
       reader.set_raw_buffer(program->kernel_data() + subprogram_start);
       reader.set_size(subprogram_end - subprogram_start);
       reader.set_offset(0);
-      Program* subprogram = Program::ReadFrom(&reader);
+      std::unique_ptr<Program> subprogram = Program::ReadFrom(&reader);
       ASSERT(subprogram->is_single_program());
-      KernelLoader loader(subprogram, /*uri_to_source_table=*/nullptr);
+      KernelLoader loader(subprogram.get(), /*uri_to_source_table=*/nullptr);
       loader.walk_incremental_kernel(modified_libs, is_empty_program,
                                      p_num_classes, p_num_procedures);
-      delete subprogram;
     }
   }
 }
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index adba2b0..4e5f849 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -11334,7 +11334,7 @@
       String::New("Expression evaluation not available in precompiled mode."));
   return ApiError::New(error_str);
 #else
-  kernel::Program* kernel_pgm =
+  std::unique_ptr<kernel::Program> kernel_pgm =
       kernel::Program::ReadFromBuffer(kernel_bytes, kernel_length);
 
   if (kernel_pgm == NULL) {
@@ -11342,12 +11342,11 @@
         String::New("Kernel isolate returned ill-formed kernel.")));
   }
 
-  kernel::KernelLoader loader(kernel_pgm, /*uri_to_source_table=*/nullptr);
+  kernel::KernelLoader loader(kernel_pgm.get(),
+                              /*uri_to_source_table=*/nullptr);
   const Object& result = Object::Handle(
       loader.LoadExpressionEvaluationFunction(library_url, klass));
-
-  delete kernel_pgm;
-  kernel_pgm = NULL;
+  kernel_pgm.reset();
 
   if (result.IsError()) return result.raw();