// Copyright (c) 2012, 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.

#include "vm/unit_test.h"

#include <stdio.h>

#include "bin/builtin.h"
#include "bin/dartutils.h"
#include "bin/isolate_data.h"

#include "platform/globals.h"

#include "vm/ast_printer.h"
#include "vm/compiler/assembler/assembler.h"
#include "vm/compiler/assembler/disassembler.h"
#include "vm/compiler/jit/compiler.h"
#include "vm/dart_api_impl.h"
#include "vm/isolate_reload.h"
#include "vm/kernel_isolate.h"
#include "vm/parser.h"
#include "vm/symbols.h"
#include "vm/thread.h"
#include "vm/virtual_memory.h"

using dart::bin::Builtin;
using dart::bin::DartUtils;

extern "C" {
extern const uint8_t kPlatformStrongDill[];
extern intptr_t kPlatformStrongDillSize;
}

namespace dart {

const uint8_t* platform_strong_dill = kPlatformStrongDill;
const intptr_t platform_strong_dill_size = kPlatformStrongDillSize;

const uint8_t* TesterState::vm_snapshot_data = NULL;
Dart_IsolateCreateCallback TesterState::create_callback = NULL;
Dart_IsolateShutdownCallback TesterState::shutdown_callback = NULL;
Dart_IsolateCleanupCallback TesterState::cleanup_callback = NULL;

DEFINE_FLAG(bool,
            use_dart_frontend,
            true,
            "Parse scripts with Dart-to-Kernel parser");

DECLARE_FLAG(bool, strong);

void KernelBufferList::AddBufferToList(const uint8_t* kernel_buffer) {
  next_ = new KernelBufferList(kernel_buffer_, next_);
  kernel_buffer_ = kernel_buffer;
}

TestCaseBase* TestCaseBase::first_ = NULL;
TestCaseBase* TestCaseBase::tail_ = NULL;
KernelBufferList* TestCaseBase::current_kernel_buffers_ = NULL;

TestCaseBase::TestCaseBase(const char* name)
    : raw_test_(false), next_(NULL), name_(name) {
  if (first_ == NULL) {
    first_ = this;
  } else {
    tail_->next_ = this;
  }
  tail_ = this;
}

void TestCaseBase::RunAllRaw() {
  TestCaseBase* test = first_;
  while (test != NULL) {
    if (test->raw_test_) {
      test->RunTest();
      CleanupState();
    }
    test = test->next_;
  }
}

void TestCaseBase::RunAll() {
  TestCaseBase* test = first_;
  while (test != NULL) {
    if (!test->raw_test_) {
      test->RunTest();
      CleanupState();
    }
    test = test->next_;
  }
}

void TestCaseBase::CleanupState() {
  if (current_kernel_buffers_ != NULL) {
    delete current_kernel_buffers_;
    current_kernel_buffers_ = NULL;
  }
}

void TestCaseBase::AddToKernelBuffers(const uint8_t* kernel_buffer) {
  ASSERT(kernel_buffer != NULL);
  if (current_kernel_buffers_ == NULL) {
    current_kernel_buffers_ = new KernelBufferList(kernel_buffer);
  } else {
    current_kernel_buffers_->AddBufferToList(kernel_buffer);
  }
}

Dart_Isolate TestCase::CreateIsolate(const uint8_t* data_buffer,
                                     intptr_t len,
                                     const uint8_t* instr_buffer,
                                     const char* name,
                                     void* data) {
  char* err;
  Dart_IsolateFlags api_flags;
  Isolate::FlagsInitialize(&api_flags);
  api_flags.use_dart_frontend = FLAG_use_dart_frontend;
  Dart_Isolate isolate = NULL;
  if (len == 0) {
    isolate = Dart_CreateIsolate(name, NULL, data_buffer, instr_buffer, NULL,
                                 NULL, &api_flags, data, &err);
  } else {
    isolate = Dart_CreateIsolateFromKernel(name, NULL, data_buffer, len,
                                           &api_flags, data, &err);
  }
  if (isolate == NULL) {
    OS::PrintErr("Creation of isolate failed '%s'\n", err);
    free(err);
  }
  EXPECT(isolate != NULL);
  return isolate;
}

Dart_Isolate TestCase::CreateTestIsolate(const char* name, void* data) {
  if (FLAG_use_dart_frontend) {
    return CreateIsolate(
        platform_strong_dill, platform_strong_dill_size,
        NULL, /* There is no instr buffer in case of dill buffers. */
        name, data);
  } else {
    return CreateIsolate(bin::core_isolate_snapshot_data,
                         0 /* Snapshots have length encoded within them. */,
                         bin::core_isolate_snapshot_instructions, name, data);
  }
}

static const char* kPackageScheme = "package:";

static bool IsPackageSchemeURL(const char* url_name) {
  static const intptr_t kPackageSchemeLen = strlen(kPackageScheme);
  return (strncmp(url_name, kPackageScheme, kPackageSchemeLen) == 0);
}

struct TestLibEntry {
  const char* url;
  const char* source;
};

static MallocGrowableArray<TestLibEntry>* test_libs_ = NULL;

const char* TestCase::url() {
  return (FLAG_use_dart_frontend) ? RESOLVED_USER_TEST_URI : USER_TEST_URI;
}

void TestCase::AddTestLib(const char* url, const char* source) {
  if (test_libs_ == NULL) {
    test_libs_ = new MallocGrowableArray<TestLibEntry>();
  }
  // If the test lib is already added, replace the source.
  for (intptr_t i = 0; i < test_libs_->length(); i++) {
    if (strcmp(url, (*test_libs_)[i].url) == 0) {
      (*test_libs_)[i].source = source;
      return;
    }
  }
  TestLibEntry entry;
  entry.url = url;
  entry.source = source;
  test_libs_->Add(entry);
}

const char* TestCase::GetTestLib(const char* url) {
  if (test_libs_ == NULL) {
    return NULL;
  }
  for (intptr_t i = 0; i < test_libs_->length(); i++) {
    if (strcmp(url, (*test_libs_)[i].url) == 0) {
      return (*test_libs_)[i].source;
    }
  }
  return NULL;
}

#ifndef PRODUCT
static const char* kIsolateReloadTestLibSource =
    "void reloadTest() native 'Reload_Test';\n";

static const char* IsolateReloadTestLibUri() {
  return FLAG_use_dart_frontend ? "test:isolate_reload_helper"
                                : "file:///test:isolate_reload_helper";
}

static bool IsIsolateReloadTestLib(const char* url_name) {
  static const intptr_t kIsolateReloadTestLibUriLen =
      strlen(IsolateReloadTestLibUri());
  return (strncmp(url_name, IsolateReloadTestLibUri(),
                  kIsolateReloadTestLibUriLen) == 0);
}

static Dart_Handle IsolateReloadTestLibSource() {
  // Special library with one function.
  return DartUtils::NewString(kIsolateReloadTestLibSource);
}

static void ReloadTest(Dart_NativeArguments native_args) {
  Dart_Handle result = TestCase::TriggerReload();
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
}

static Dart_NativeFunction IsolateReloadTestNativeResolver(
    Dart_Handle name,
    int num_of_arguments,
    bool* auto_setup_scope) {
  return ReloadTest;
}

static Dart_Handle LoadIsolateReloadTestLib() {
  return TestCase::LoadTestLibrary(IsolateReloadTestLibUri(),
                                   kIsolateReloadTestLibSource,
                                   IsolateReloadTestNativeResolver);
}
#endif  // !PRODUCT

static Dart_Handle ResolvePackageUri(const char* uri_chars) {
  const int kNumArgs = 1;
  Dart_Handle dart_args[kNumArgs];
  dart_args[0] = DartUtils::NewString(uri_chars);
  return Dart_Invoke(DartUtils::LookupBuiltinLib(),
                     DartUtils::NewString("_filePathFromUri"), kNumArgs,
                     dart_args);
}

static ThreadLocalKey script_reload_key = kUnsetThreadLocalKey;

bool TestCase::UsingDartFrontend() {
  return FLAG_use_dart_frontend;
}

bool TestCase::UsingStrongMode() {
  return FLAG_strong;
}

char* TestCase::CompileTestScriptWithDFE(const char* url,
                                         const char* source,
                                         const uint8_t** kernel_buffer,
                                         intptr_t* kernel_buffer_size,
                                         bool incrementally,
                                         bool allow_compile_errors,
                                         const char* multiroot_filepaths,
                                         const char* multiroot_scheme) {
  // clang-format off
  Dart_SourceFile sourcefiles[] = {
    {
      url, source,
    },
    {
      "file:///.packages", "untitled:/"
    }};
  // clang-format on
  return CompileTestScriptWithDFE(
      url, sizeof(sourcefiles) / sizeof(Dart_SourceFile), sourcefiles,
      kernel_buffer, kernel_buffer_size, incrementally, allow_compile_errors,
      multiroot_filepaths, multiroot_scheme);
}

#if 0

char* TestCase::CompileTestScriptWithDFE(const char* url,
                                         int sourcefiles_count,
                                         Dart_SourceFile sourcefiles[],
                                         void** kernel_pgm,
                                         bool incrementally,
                                         bool allow_compile_errors) {
  Zone* zone = Thread::Current()->zone();
  Dart_KernelCompilationResult compilation_result = Dart_CompileSourcesToKernel(
      url, platform_strong_dill, platform_strong_dill_size,
      sourcefiles_count, sourcefiles, incrementally, NULL);
  return ValidateCompilationResult(zone, compilation_result, kernel_pgm);
}

char* TestCase::ValidateCompilationResult(
    Zone* zone,
    Dart_KernelCompilationResult compilation_result,
    void** kernel_pgm,
    bool allow_compile_errors) {
  if (!allow_compile_errors &&
      (compilation_result.status != Dart_KernelCompilationStatus_Ok)) {
    char* result =
        OS::SCreate(zone, "Compilation failed %s", compilation_result.error);
    free(compilation_result.error);
    return result;
  }

  const uint8_t* kernel_file = compilation_result.kernel;
  intptr_t kernel_length = compilation_result.kernel_size;
  if (kernel_file == NULL) {
    return OS::SCreate(zone, "front end generated a NULL kernel file");
  }
  *kernel_pgm =
      Dart_ReadKernelBinary(kernel_file, kernel_length, ReleaseFetchedBytes);
  if (*kernel_pgm == NULL) {
    return OS::SCreate(zone, "Failed to read generated kernel binary");
  }
  if (compilation_result.status != Dart_KernelCompilationStatus_Ok) {
    char* result =
        OS::SCreate(zone, "Compilation failed %s", compilation_result.error);
    free(compilation_result.error);
    return result;
  }
  return NULL;
}
#endif

char* TestCase::CompileTestScriptWithDFE(const char* url,
                                         int sourcefiles_count,
                                         Dart_SourceFile sourcefiles[],
                                         const uint8_t** kernel_buffer,
                                         intptr_t* kernel_buffer_size,
                                         bool incrementally,
                                         bool allow_compile_errors,
                                         const char* multiroot_filepaths,
                                         const char* multiroot_scheme) {
  Zone* zone = Thread::Current()->zone();
  Dart_KernelCompilationResult compilation_result = Dart_CompileSourcesToKernel(
      url, platform_strong_dill, platform_strong_dill_size, sourcefiles_count,
      sourcefiles, incrementally, NULL, multiroot_filepaths, multiroot_scheme);
  return ValidateCompilationResult(zone, compilation_result, kernel_buffer,
                                   kernel_buffer_size, allow_compile_errors);
}

char* TestCase::ValidateCompilationResult(
    Zone* zone,
    Dart_KernelCompilationResult compilation_result,
    const uint8_t** kernel_buffer,
    intptr_t* kernel_buffer_size,
    bool allow_compile_errors) {
  if (!allow_compile_errors &&
      (compilation_result.status != Dart_KernelCompilationStatus_Ok)) {
    char* result =
        OS::SCreate(zone, "Compilation failed %s", compilation_result.error);
    free(compilation_result.error);
    if (compilation_result.kernel != NULL) {
      free(const_cast<uint8_t*>(compilation_result.kernel));
    }
    *kernel_buffer = NULL;
    *kernel_buffer_size = 0;
    return result;
  }
  *kernel_buffer = compilation_result.kernel;
  *kernel_buffer_size = compilation_result.kernel_size;
  if (compilation_result.error != NULL) {
    free(compilation_result.error);
  }
  if (kernel_buffer == NULL) {
    return OS::SCreate(zone, "front end generated a NULL kernel file");
  }
  return NULL;
}

static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag,
                                     Dart_Handle library,
                                     Dart_Handle url) {
  if (tag == Dart_kCanonicalizeUrl) {
    Dart_Handle library_url = Dart_LibraryUrl(library);
    if (Dart_IsError(library_url)) {
      return library_url;
    }
    return Dart_DefaultCanonicalizeUrl(library_url, url);
  }
  if (tag == Dart_kScriptTag) {
    // Reload request.
    ASSERT(script_reload_key != kUnsetThreadLocalKey);
    const char* script_source = reinterpret_cast<const char*>(
        OSThread::GetThreadLocal(script_reload_key));
    ASSERT(script_source != NULL);
    OSThread::SetThreadLocal(script_reload_key, 0);
    return Dart_LoadScript(url, Dart_Null(), NewString(script_source), 0, 0);
  }
  if (!Dart_IsLibrary(library)) {
    return Dart_NewApiError("not a library");
  }
  if (!Dart_IsString(url)) {
    return Dart_NewApiError("url is not a string");
  }
  const char* url_chars = NULL;
  Dart_Handle result = Dart_StringToCString(url, &url_chars);
  if (Dart_IsError(result)) {
    return Dart_NewApiError("accessing url characters failed");
  }
  Dart_Handle library_url = Dart_LibraryUrl(library);
  const char* library_url_string = NULL;
  result = Dart_StringToCString(library_url, &library_url_string);
  if (Dart_IsError(result)) {
    return result;
  }

  bool is_dart_scheme_url = DartUtils::IsDartSchemeURL(url_chars);
  bool is_io_library = DartUtils::IsDartIOLibURL(library_url_string);
  bool is_standalone_library = DartUtils::IsDartCLILibURL(library_url_string);
  if (is_dart_scheme_url) {
    ASSERT(tag == Dart_kImportTag);
    // Handle imports of other built-in libraries present in the SDK.
    if (DartUtils::IsDartIOLibURL(url_chars)) {
      return Builtin::LoadAndCheckLibrary(Builtin::kIOLibrary);
    } else if (DartUtils::IsDartBuiltinLibURL(url_chars)) {
      return Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
    } else if (DartUtils::IsDartCLILibURL(url_chars)) {
      return Builtin::LoadAndCheckLibrary(Builtin::kCLILibrary);
    } else {
      return DartUtils::NewError("Do not know how to load '%s'", url_chars);
    }
  }
  const char* lib_source = TestCase::GetTestLib(url_chars);
  if (lib_source != NULL) {
    Dart_Handle source = Dart_NewStringFromCString(lib_source);
    return Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
  }
#if !defined(PRODUCT)
  if (IsIsolateReloadTestLib(url_chars)) {
    Dart_Handle library =
        Dart_LoadLibrary(url, Dart_Null(), IsolateReloadTestLibSource(), 0, 0);
    DART_CHECK_VALID(library);
    Dart_SetNativeResolver(library, IsolateReloadTestNativeResolver, 0);
    return library;
  }
#endif
  if (is_io_library) {
    ASSERT(tag == Dart_kSourceTag);
    return Dart_LoadSource(library, url, Dart_Null(),
                           Builtin::PartSource(Builtin::kIOLibrary, url_chars),
                           0, 0);
  }
  if (is_standalone_library) {
    ASSERT(tag == Dart_kSourceTag);
    return Dart_LoadSource(library, url, Dart_Null(),
                           Builtin::PartSource(Builtin::kCLILibrary, url_chars),
                           0, 0);
  }
  Dart_Handle resolved_url = url;
  const char* resolved_url_chars = url_chars;
  if (IsPackageSchemeURL(url_chars)) {
    resolved_url = ResolvePackageUri(url_chars);
    DART_CHECK_VALID(resolved_url);
    if (Dart_IsError(Dart_StringToCString(resolved_url, &resolved_url_chars))) {
      return Dart_NewApiError("unable to convert resolved uri to string");
    }
  }
  // Do sync loading since unit_test doesn't support async.
  Dart_Handle source = DartUtils::ReadStringFromFile(resolved_url_chars);
  EXPECT_VALID(source);
  if (tag == Dart_kImportTag) {
    return Dart_LoadLibrary(url, resolved_url, source, 0, 0);
  } else {
    ASSERT(tag == Dart_kSourceTag);
    return Dart_LoadSource(library, url, resolved_url, source, 0, 0);
  }
}

static Dart_Handle LoadTestScriptWithVMParser(const char* script,
                                              Dart_NativeEntryResolver resolver,
                                              const char* lib_url,
                                              bool finalize_classes) {
  Dart_Handle url = NewString(lib_url);
  Dart_Handle source = NewString(script);
  Dart_Handle result = Dart_SetLibraryTagHandler(LibraryTagHandler);
  EXPECT_VALID(result);
  Dart_Handle lib = Dart_LoadScript(url, Dart_Null(), source, 0, 0);
  DART_CHECK_VALID(lib);
  result = Dart_SetNativeResolver(lib, resolver, NULL);
  DART_CHECK_VALID(result);
  if (finalize_classes) {
    result = Dart_FinalizeLoading(false);
    DART_CHECK_VALID(result);
  }
  return lib;
}

static intptr_t BuildSourceFilesArray(Dart_SourceFile** sourcefiles,
                                      const char* script) {
  ASSERT(sourcefiles != NULL);
  ASSERT(script != NULL);
  ASSERT(FLAG_use_dart_frontend);

  intptr_t num_test_libs = 0;
  if (test_libs_ != NULL) {
    num_test_libs = test_libs_->length();
  }

  *sourcefiles = new Dart_SourceFile[num_test_libs + 1];
  (*sourcefiles)[0].uri = RESOLVED_USER_TEST_URI;
  (*sourcefiles)[0].source = script;
  for (intptr_t i = 0; i < num_test_libs; ++i) {
    (*sourcefiles)[i + 1].uri = test_libs_->At(i).url;
    (*sourcefiles)[i + 1].source = test_libs_->At(i).source;
  }
  return num_test_libs + 1;
}

Dart_Handle TestCase::LoadTestScriptWithErrors(
    const char* script,
    Dart_NativeEntryResolver resolver,
    const char* lib_url,
    bool finalize_classes) {
  return LoadTestScript(script, resolver, lib_url, finalize_classes, true);
}

Dart_Handle TestCase::LoadTestScript(const char* script,
                                     Dart_NativeEntryResolver resolver,
                                     const char* lib_url,
                                     bool finalize_classes,
                                     bool allow_compile_errors) {
  if (FLAG_use_dart_frontend) {
#ifndef PRODUCT
    if (strstr(script, IsolateReloadTestLibUri()) != NULL) {
      Dart_Handle result = LoadIsolateReloadTestLib();
      EXPECT_VALID(result);
    }
#endif  // ifndef PRODUCT
    Dart_SourceFile* sourcefiles = NULL;
    intptr_t num_sources = BuildSourceFilesArray(&sourcefiles, script);
    Dart_Handle result =
        LoadTestScriptWithDFE(num_sources, sourcefiles, resolver,
                              finalize_classes, true, allow_compile_errors);
    delete[] sourcefiles;
    return result;
  } else {
    return LoadTestScriptWithVMParser(script, resolver, lib_url,
                                      finalize_classes);
  }
}

Dart_Handle TestCase::LoadTestLibrary(const char* lib_uri,
                                      const char* script,
                                      Dart_NativeEntryResolver resolver) {
  if (FLAG_use_dart_frontend) {
    const char* prefixed_lib_uri =
        OS::SCreate(Thread::Current()->zone(), "file:///%s", lib_uri);
    Dart_SourceFile sourcefiles[] = {{prefixed_lib_uri, script}};
    const uint8_t* kernel_buffer = NULL;
    intptr_t kernel_buffer_size = 0;
    int sourcefiles_count = sizeof(sourcefiles) / sizeof(Dart_SourceFile);
    char* error = TestCase::CompileTestScriptWithDFE(
        sourcefiles[0].uri, sourcefiles_count, sourcefiles, &kernel_buffer,
        &kernel_buffer_size, true);
    if ((kernel_buffer == NULL) && (error != NULL)) {
      return Dart_NewApiError(error);
    }
    Dart_Handle lib =
        Dart_LoadLibraryFromKernel(kernel_buffer, kernel_buffer_size);
    EXPECT_VALID(lib);

    // Ensure kernel buffer isn't leaked after test is run.
    AddToKernelBuffers(kernel_buffer);

    // TODO(32618): Kernel doesn't correctly represent the root library.
    lib = Dart_LookupLibrary(Dart_NewStringFromCString(sourcefiles[0].uri));
    DART_CHECK_VALID(lib);
    Dart_Handle result = Dart_SetRootLibrary(lib);
    DART_CHECK_VALID(result);

    Dart_SetNativeResolver(lib, resolver, NULL);
    return lib;
  } else {
    Dart_Handle url = NewString(lib_uri);
    Dart_Handle source = NewString(script);
    return Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
  }
}

Dart_Handle TestCase::LoadTestScriptWithDFE(int sourcefiles_count,
                                            Dart_SourceFile sourcefiles[],
                                            Dart_NativeEntryResolver resolver,
                                            bool finalize,
                                            bool incrementally,
                                            bool allow_compile_errors,
                                            const char* entry_script_uri,
                                            const char* multiroot_filepaths,
                                            const char* multiroot_scheme) {
  // First script is the main script.
  Dart_Handle result = Dart_SetLibraryTagHandler(LibraryTagHandler);
  EXPECT_VALID(result);
  const uint8_t* kernel_buffer = NULL;
  intptr_t kernel_buffer_size = 0;
  char* error = TestCase::CompileTestScriptWithDFE(
      entry_script_uri != NULL ? entry_script_uri : sourcefiles[0].uri,
      sourcefiles_count, sourcefiles, &kernel_buffer, &kernel_buffer_size,
      incrementally, allow_compile_errors, multiroot_filepaths,
      multiroot_scheme);
  if ((kernel_buffer == NULL) && error != NULL) {
    return Dart_NewApiError(error);
  }

  Dart_Handle lib =
      Dart_LoadLibraryFromKernel(kernel_buffer, kernel_buffer_size);
  DART_CHECK_VALID(lib);

  // Ensure kernel buffer isn't leaked after test is run.
  AddToKernelBuffers(kernel_buffer);

  // BOGUS: Kernel doesn't correctly represent the root library.
  lib = Dart_LookupLibrary(Dart_NewStringFromCString(
      entry_script_uri != NULL ? entry_script_uri : sourcefiles[0].uri));
  DART_CHECK_VALID(lib);
  result = Dart_SetRootLibrary(lib);
  DART_CHECK_VALID(result);

  result = Dart_SetNativeResolver(lib, resolver, NULL);
  DART_CHECK_VALID(result);
  if (finalize) {
    result = Dart_FinalizeLoading(false);
    DART_CHECK_VALID(result);
  }
  return lib;
}

#ifndef PRODUCT

Dart_Handle TestCase::SetReloadTestScript(const char* script) {
  if (FLAG_use_dart_frontend) {
    Dart_SourceFile* sourcefiles = NULL;
    intptr_t num_files = BuildSourceFilesArray(&sourcefiles, script);
    Dart_KernelCompilationResult compilation_result =
        KernelIsolate::UpdateInMemorySources(num_files, sourcefiles);
    delete[] sourcefiles;
    if (compilation_result.status != Dart_KernelCompilationStatus_Ok) {
      Dart_Handle result = Dart_NewApiError(compilation_result.error);
      free(compilation_result.error);
      return result;
    }
    return Api::Success();
  } else {
    if (script_reload_key == kUnsetThreadLocalKey) {
      script_reload_key = OSThread::CreateThreadLocal();
    }
    ASSERT(script_reload_key != kUnsetThreadLocalKey);
    ASSERT(OSThread::GetThreadLocal(script_reload_key) == 0);
    // Store the new script in TLS.
    OSThread::SetThreadLocal(script_reload_key,
                             reinterpret_cast<uword>(script));
    return Api::Success();
  }
}

Dart_Handle TestCase::TriggerReload() {
  Thread* thread = Thread::Current();
  Isolate* isolate = thread->isolate();
  JSONStream js;
  bool success = false;
  {
    TransitionNativeToVM transition(thread);
    success = isolate->ReloadSources(&js,
                                     false,  // force_reload
                                     NULL, NULL,
                                     true);  // dont_delete_reload_context
    OS::PrintErr("RELOAD REPORT:\n%s\n", js.ToCString());
  }

  Dart_Handle result = Dart_Null();
  if (success) {
    result = Dart_FinalizeLoading(false);
  }

  if (Dart_IsError(result)) {
    // Keep load error.
  } else if (isolate->reload_context()->reload_aborted()) {
    TransitionNativeToVM transition(thread);
    result = Api::NewHandle(thread, isolate->reload_context()->error());
  } else {
    result = Dart_RootLibrary();
  }

  TransitionNativeToVM transition(thread);
  if (isolate->reload_context() != NULL) {
    isolate->DeleteReloadContext();
  }

  return result;
}

Dart_Handle TestCase::ReloadTestScript(const char* script) {
  if (FLAG_use_dart_frontend) {
    Dart_SourceFile* sourcefiles = NULL;
    intptr_t num_files = BuildSourceFilesArray(&sourcefiles, script);
    Dart_KernelCompilationResult compilation_result =
        KernelIsolate::UpdateInMemorySources(num_files, sourcefiles);
    delete[] sourcefiles;
    if (compilation_result.status != Dart_KernelCompilationStatus_Ok) {
      Dart_Handle result = Dart_NewApiError(compilation_result.error);
      free(compilation_result.error);
      if (compilation_result.kernel != NULL) {
        free(const_cast<uint8_t*>(compilation_result.kernel));
      }
      return result;
    }
  } else {
    SetReloadTestScript(script);
  }
  return TriggerReload();
}

Dart_Handle TestCase::ReloadTestKernel(const uint8_t* kernel_buffer,
                                       intptr_t kernel_buffer_size) {
  return TriggerReload();
}

#endif  // !PRODUCT

Dart_Handle TestCase::LoadCoreTestScript(const char* script,
                                         Dart_NativeEntryResolver resolver) {
  return LoadTestScript(script, resolver, CORELIB_TEST_URI);
}

Dart_Handle TestCase::lib() {
  Dart_Handle url = NewString(TestCase::url());
  Dart_Handle lib = Dart_LookupLibrary(url);
  DART_CHECK_VALID(lib);
  ASSERT(Dart_IsLibrary(lib));
  return lib;
}

Dart_Handle TestCase::library_handler(Dart_LibraryTag tag,
                                      Dart_Handle library,
                                      Dart_Handle url) {
  if (tag == Dart_kCanonicalizeUrl) {
    return url;
  }
  return Api::Success();
}

Dart_Handle TestCase::EvaluateExpression(const Library& lib,
                                         const String& expr,
                                         const Array& param_names,
                                         const Array& param_values) {
  Thread* thread = Thread::Current();

  Object& val = Object::Handle();
  if (!KernelIsolate::IsRunning()) {
    val = lib.Evaluate(expr, param_names, param_values);
  } else {
    Dart_KernelCompilationResult compilation_result;
    {
      TransitionVMToNative transition(thread);
      compilation_result = KernelIsolate::CompileExpressionToKernel(
          expr.ToCString(), param_names, Array::empty_array(),
          String::Handle(lib.url()).ToCString(), /* klass=*/nullptr,
          /* is_static= */ false);
    }
    if (compilation_result.status != Dart_KernelCompilationStatus_Ok) {
      return Dart_NewApiError(compilation_result.error);
    }

    const uint8_t* kernel_bytes = compilation_result.kernel;
    intptr_t kernel_length = compilation_result.kernel_size;

    val = lib.EvaluateCompiledExpression(kernel_bytes, kernel_length,
                                         Array::empty_array(), param_values,
                                         TypeArguments::null_type_arguments());

    free(const_cast<uint8_t*>(kernel_bytes));
  }
  return Api::NewHandle(thread, val.raw());
}

#if !defined(PRODUCT)
static bool IsHex(int c) {
  return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f');
}
#endif

void AssemblerTest::Assemble() {
  const String& function_name =
      String::ZoneHandle(Symbols::New(Thread::Current(), name_));

  // We make a dummy script so that exception objects can be composed for
  // assembler instructions that do runtime calls, in particular on DBC.
  const char* kDummyScript = "assembler_test_dummy_function() {}";
  const Script& script = Script::Handle(
      Script::New(function_name, String::Handle(String::New(kDummyScript)),
                  RawScript::kSourceTag));
  script.Tokenize(String::Handle());
  const Library& lib = Library::Handle(Library::CoreLibrary());
  const Class& cls = Class::ZoneHandle(
      Class::New(lib, function_name, script, TokenPosition::kMinSource));
  Function& function = Function::ZoneHandle(
      Function::New(function_name, RawFunction::kRegularFunction, true, false,
                    false, false, false, cls, TokenPosition::kMinSource));
  code_ = Code::FinalizeCode(function, nullptr, assembler_);
  code_.set_owner(function);
  code_.set_exception_handlers(Object::empty_exception_handlers());
#ifndef PRODUCT
  const Instructions& instructions = Instructions::Handle(code_.instructions());
  uword start = instructions.PayloadStart();
  if (FLAG_disassemble) {
    OS::PrintErr("Code for test '%s' {\n", name_);
    uword start = instructions.PayloadStart();
    Disassembler::Disassemble(start, start + assembler_->CodeSize());
    OS::PrintErr("}\n");
  }
  Disassembler::Disassemble(start, start + assembler_->CodeSize(), disassembly_,
                            DISASSEMBLY_SIZE);
  // Blank out big hex constants, since they are not stable from run to run.
  bool in_hex_constant = false;
  for (char* p = disassembly_; *p != '\0'; p++) {
    if (in_hex_constant) {
      if (IsHex(*p)) {
        *p = '.';
      } else {
        in_hex_constant = false;
      }
    } else {
      if (*p == '0' && *(p + 1) == 'x' && IsHex(*(p + 2)) && IsHex(*(p + 3)) &&
          IsHex(*(p + 4))) {
        p++;
        in_hex_constant = true;
      }
    }
  }
#endif  // !PRODUCT
}

CodeGenTest::CodeGenTest(const char* name)
    : function_(Function::ZoneHandle()),
      node_sequence_(new SequenceNode(TokenPosition::kMinSource,
                                      new LocalScope(NULL, 0, 0))),
      default_parameter_values_(new ZoneGrowableArray<const Instance*>()) {
  ASSERT(name != NULL);
  const String& function_name =
      String::ZoneHandle(Symbols::New(Thread::Current(), name));
  // Add function to a class and that class to the class dictionary so that
  // frame walking can be used.
  Library& lib = Library::Handle(Library::CoreLibrary());
  const Class& cls = Class::ZoneHandle(Class::New(
      lib, function_name, Script::Handle(), TokenPosition::kMinSource));
  function_ =
      Function::New(function_name, RawFunction::kRegularFunction, true, false,
                    false, false, false, cls, TokenPosition::kMinSource);
  function_.set_result_type(Type::Handle(Type::DynamicType()));
  const Array& functions = Array::Handle(Array::New(1));
  functions.SetAt(0, function_);
  cls.SetFunctions(functions);
  lib.AddClass(cls);
}

void CodeGenTest::Compile() {
  if (function_.HasCode()) return;
  ParsedFunction* parsed_function =
      new ParsedFunction(Thread::Current(), function_);
  parsed_function->SetNodeSequence(node_sequence_);
  parsed_function->set_default_parameter_values(default_parameter_values_);
  node_sequence_->scope()->AddVariable(parsed_function->current_context_var());
  parsed_function->EnsureExpressionTemp();
  node_sequence_->scope()->AddVariable(parsed_function->expression_temp_var());
  parsed_function->AllocateVariables();
  const Error& error =
      Error::Handle(Compiler::CompileParsedFunction(parsed_function));
  EXPECT(error.IsNull());
}

bool CompilerTest::TestCompileScript(const Library& library,
                                     const Script& script) {
  Isolate* isolate = Isolate::Current();
  ASSERT(isolate != NULL);
  const Error& error = Error::Handle(Compiler::Compile(library, script));
  if (!error.IsNull()) {
    OS::PrintErr("Error compiling test script:\n%s\n", error.ToErrorCString());
  }
  return error.IsNull();
}

bool CompilerTest::TestCompileFunction(const Function& function) {
  Thread* thread = Thread::Current();
  ASSERT(thread != NULL);
  ASSERT(ClassFinalizer::AllClassesFinalized());
  const Object& result =
      Object::Handle(Compiler::CompileFunction(thread, function));
  return result.IsCode();
}

void ElideJSONSubstring(const char* prefix, const char* in, char* out) {
  const char* pos = strstr(in, prefix);
  while (pos != NULL) {
    // Copy up to pos into the output buffer.
    while (in < pos) {
      *out++ = *in++;
    }

    // Skip to the close quote.
    in += strcspn(in, "\"");
    pos = strstr(in, prefix);
  }
  // Copy the remainder of in to out.
  while (*in != '\0') {
    *out++ = *in++;
  }
  *out = '\0';
}

}  // namespace dart
