// 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 "bin/uri.h"

#include "platform/globals.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 kPlatformDill[];
extern intptr_t kPlatformDillSize;
}

namespace dart {

DECLARE_FLAG(bool, gc_during_reload);
DECLARE_FLAG(bool, force_evacuation);

const uint8_t* platform_dill = kPlatformDill;
const intptr_t platform_dill_size = kPlatformDillSize;

const uint8_t* TesterState::vm_snapshot_data = nullptr;
Dart_IsolateGroupCreateCallback TesterState::create_callback = nullptr;
Dart_IsolateShutdownCallback TesterState::shutdown_callback = nullptr;
Dart_IsolateGroupCleanupCallback TesterState::group_cleanup_callback = nullptr;
const char** TesterState::argv = nullptr;
int TesterState::argc = 0;

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

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

TestCaseBase::TestCaseBase(const char* name, const char* expectation)
    : raw_test_(false),
      next_(nullptr),
      name_(name),
      expectation_(strlen(expectation) > 0 ? expectation : "Pass") {
  if (first_ == nullptr) {
    first_ = this;
  } else {
    tail_->next_ = this;
  }
  tail_ = this;
}

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

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

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

void TestCaseBase::AddToKernelBuffers(const uint8_t* kernel_buffer) {
  ASSERT(kernel_buffer != nullptr);
  if (current_kernel_buffers_ == nullptr) {
    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* group_data,
                                     void* isolate_data) {
  char* err;
  Dart_IsolateFlags api_flags;
  Isolate::FlagsInitialize(&api_flags);
  api_flags.null_safety = true;
  Dart_Isolate isolate = nullptr;
  if (len == 0) {
    isolate = Dart_CreateIsolateGroup(
        /*script_uri=*/name, /*name=*/name, data_buffer, instr_buffer,
        &api_flags, group_data, isolate_data, &err);
  } else {
    isolate = Dart_CreateIsolateGroupFromKernel(/*script_uri=*/name,
                                                /*name=*/name, data_buffer, len,
                                                &api_flags, group_data,
                                                isolate_data, &err);
  }
  if (isolate == nullptr) {
    OS::PrintErr("Creation of isolate failed '%s'\n", err);
    free(err);
  }

  EXPECT(isolate != nullptr);
  return isolate;
}

Dart_Isolate TestCase::CreateTestIsolate(const char* name,
                                         void* group_data,
                                         void* isolate_data) {
  return CreateIsolate(bin::core_isolate_snapshot_data,
                       0 /* Snapshots have length encoded within them. */,
                       bin::core_isolate_snapshot_instructions, name,
                       group_data, isolate_data);
}

void SetupCoreLibrariesForUnitTest() {
  TransitionVMToNative transition(Thread::Current());

  Dart_EnterScope();
  bool ok = bin::DartUtils::SetOriginalWorkingDirectory();
  RELEASE_ASSERT(ok);
  Dart_Handle result = bin::DartUtils::PrepareForScriptLoading(
      /*is_service_isolate=*/false,
      /*trace_loading=*/false, /*flag_profile_microtasks=*/false);
  Dart_ExitScope();

  RELEASE_ASSERT(!Dart_IsError(result));
}

Dart_Isolate TestCase::CreateTestIsolateInGroup(const char* name,
                                                Dart_Isolate parent,
                                                void* group_data,
                                                void* isolate_data) {
  char* error;
  Isolate* result = CreateWithinExistingIsolateGroup(
      reinterpret_cast<Isolate*>(parent)->group(), name, &error);
  if (error != nullptr) {
    OS::PrintErr("CreateTestIsolateInGroup failed: %s\n", error);
    free(error);
  }
  EXPECT(result != nullptr);
  return Api::CastIsolate(result);
}

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

static MallocGrowableArray<TestLibEntry>* test_libs_ = nullptr;

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

void TestCase::AddTestLib(const char* url, const char* source) {
  if (test_libs_ == nullptr) {
    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_ == nullptr) {
    return nullptr;
  }
  for (intptr_t i = 0; i < test_libs_->length(); i++) {
    if (strcmp(url, (*test_libs_)[i].url) == 0) {
      return (*test_libs_)[i].source;
    }
  }
  return nullptr;
}

#ifndef PRODUCT
static const char* kIsolateReloadTestLibSource = R"(
@pragma("vm:external-name", "Test_Reload")
external void reloadTest();
@pragma("vm:external-name", "Test_CollectNewSpace")
external void collectNewSpace();
@pragma("vm:external-name", "Test_CollectOldSpace")
external void collectOldSpace();
)";

static const char* IsolateReloadTestLibUri() {
  return "test:isolate_reload_helper";
}

#define RELOAD_NATIVE_LIST(V)                                                  \
  V(Test_Reload, 0)                                                            \
  V(Test_CollectNewSpace, 0)                                                   \
  V(Test_CollectOldSpace, 0)

RELOAD_NATIVE_LIST(DECLARE_FUNCTION);

static struct NativeEntries {
  const char* name_;
  Dart_NativeFunction function_;
  int argument_count_;
} ReloadEntries[] = {RELOAD_NATIVE_LIST(REGISTER_FUNCTION)};

static Dart_NativeFunction IsolateReloadTestNativeResolver(
    Dart_Handle name,
    int argument_count,
    bool* auto_setup_scope) {
  const char* function_name = nullptr;
  Dart_Handle result = Dart_StringToCString(name, &function_name);
  ASSERT(!Dart_IsError(result));
  ASSERT(function_name != nullptr);
  ASSERT(auto_setup_scope != nullptr);
  *auto_setup_scope = true;
  int num_entries = sizeof(ReloadEntries) / sizeof(struct NativeEntries);
  for (int i = 0; i < num_entries; i++) {
    struct NativeEntries* entry = &(ReloadEntries[i]);
    if ((strcmp(function_name, entry->name_) == 0) &&
        (entry->argument_count_ == argument_count)) {
      return reinterpret_cast<Dart_NativeFunction>(entry->function_);
    }
  }
  return nullptr;
}

void FUNCTION_NAME(Test_Reload)(Dart_NativeArguments native_args) {
  Dart_Handle result = TestCase::TriggerReload(/* kernel_buffer= */ nullptr,
                                               /* kernel_buffer_size= */ 0);
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
}

void FUNCTION_NAME(Test_CollectNewSpace)(Dart_NativeArguments native_args) {
  TransitionNativeToVM transition(Thread::Current());
  GCTestHelper::CollectNewSpace();
}

void FUNCTION_NAME(Test_CollectOldSpace)(Dart_NativeArguments native_args) {
  TransitionNativeToVM transition(Thread::Current());
  GCTestHelper::CollectOldSpace();
}

#endif  // !PRODUCT

static void LoadIsolateReloadTestLibIfNeeded(const char* script) {
#ifndef PRODUCT
  if (strstr(script, IsolateReloadTestLibUri()) != nullptr) {
    Dart_Handle result = TestCase::LoadTestLibrary(
        IsolateReloadTestLibUri(), kIsolateReloadTestLibSource,
        IsolateReloadTestNativeResolver);
    EXPECT_VALID(result);
  }
#endif  // ifndef PRODUCT
}

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

char* TestCase::CompileTestScriptWithDFE(const char* url,
                                         int sourcefiles_count,
                                         Dart_SourceFile sourcefiles[],
                                         const uint8_t** kernel_buffer,
                                         intptr_t* kernel_buffer_size,
                                         bool incrementally,
                                         const char* multiroot_filepaths,
                                         const char* multiroot_scheme) {
  Zone* zone = Thread::Current()->zone();
  Dart_KernelCompilationResult result = KernelIsolate::CompileToKernel(
      url, platform_dill, platform_dill_size, sourcefiles_count, sourcefiles,
      incrementally, /*for_snapshot=*/false,
      /*embed_sources=*/true, nullptr, multiroot_filepaths, multiroot_scheme);
  if (result.status == Dart_KernelCompilationStatus_Ok) {
    if (KernelIsolate::AcceptCompilation().status !=
        Dart_KernelCompilationStatus_Ok) {
      FATAL(
          "An error occurred in the CFE while accepting the most recent"
          " compilation results.");
    }
  }
  return ValidateCompilationResult(zone, result, kernel_buffer,
                                   kernel_buffer_size);
}

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

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;
    }

    const char* library_url_cstr;
    Dart_Handle result = Dart_StringToCString(library_url, &library_url_cstr);
    if (Dart_IsError(result)) {
      return result;
    }
    const char* url_cstr;
    result = Dart_StringToCString(url, &url_cstr);
    if (Dart_IsError(result)) {
      return result;
    }
    CStringUniquePtr resolved_uri = ResolveUri(url_cstr, library_url_cstr);
    if (!resolved_uri) {
      return DartUtils::NewError("%s: Unable to canonicalize uri '%s'.",
                                 __FUNCTION__, url_cstr);
    }
    result = Dart_NewStringFromCString(resolved_uri.get());
    return result;
  }
  UNREACHABLE();
  return Dart_Null();
}

static intptr_t BuildSourceFilesArray(
    Dart_SourceFile** sourcefiles,
    const char* script,
    const char* script_url = RESOLVED_USER_TEST_URI) {
  ASSERT(sourcefiles != nullptr);
  ASSERT(script != nullptr);

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

  *sourcefiles = new Dart_SourceFile[num_test_libs + 1];
  (*sourcefiles)[0].uri = script_url;
  (*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::LoadTestScript(const char* script,
                                     Dart_NativeEntryResolver resolver,
                                     const char* lib_url,
                                     bool finalize_classes) {
  LoadIsolateReloadTestLibIfNeeded(script);
  Dart_SourceFile* sourcefiles = nullptr;
  intptr_t num_sources = BuildSourceFilesArray(&sourcefiles, script, lib_url);
  Dart_Handle result = LoadTestScriptWithDFE(num_sources, sourcefiles, resolver,
                                             finalize_classes, true);
  delete[] sourcefiles;
  return result;
}

static void MallocFinalizer(void* isolate_callback_data, void* peer) {
  free(peer);
}

Dart_Handle TestCase::LoadTestLibrary(const char* lib_uri,
                                      const char* script,
                                      Dart_NativeEntryResolver resolver) {
  LoadIsolateReloadTestLibIfNeeded(script);
  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 = nullptr;
  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 (error != nullptr) {
    return Dart_NewApiError(error);
  }

  Dart_Handle td = Dart_NewExternalTypedDataWithFinalizer(
      Dart_TypedData_kUint8, const_cast<uint8_t*>(kernel_buffer),
      kernel_buffer_size, const_cast<uint8_t*>(kernel_buffer),
      kernel_buffer_size, MallocFinalizer);
  EXPECT_VALID(td);
  Dart_Handle lib = Dart_IsBytecode(kernel_buffer, kernel_buffer_size)
                        ? Dart_LoadLibraryFromBytecode(td)
                        : Dart_LoadLibrary(td);
  EXPECT_VALID(lib);

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

  Dart_SetNativeResolver(lib, resolver, nullptr);
  return lib;
}

Dart_Handle TestCase::LoadTestScriptWithDFE(int sourcefiles_count,
                                            Dart_SourceFile sourcefiles[],
                                            Dart_NativeEntryResolver resolver,
                                            bool finalize,
                                            bool incrementally,
                                            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 = nullptr;
  intptr_t kernel_buffer_size = 0;
  char* error = TestCase::CompileTestScriptWithDFE(
      entry_script_uri != nullptr ? entry_script_uri : sourcefiles[0].uri,
      sourcefiles_count, sourcefiles, &kernel_buffer, &kernel_buffer_size,
      incrementally, multiroot_filepaths, multiroot_scheme);
  if (error != nullptr) {
    return Dart_NewApiError(error);
  }

  Dart_Handle td = Dart_NewExternalTypedDataWithFinalizer(
      Dart_TypedData_kUint8, const_cast<uint8_t*>(kernel_buffer),
      kernel_buffer_size, const_cast<uint8_t*>(kernel_buffer),
      kernel_buffer_size, MallocFinalizer);
  EXPECT_VALID(td);
  Dart_Handle lib = Dart_IsBytecode(kernel_buffer, kernel_buffer_size)
                        ? Dart_LoadLibraryFromBytecode(td)
                        : Dart_LoadLibrary(td);
  EXPECT_VALID(lib);

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

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

#ifndef PRODUCT

Dart_Handle TestCase::SetReloadTestScript(const char* script) {
  // For our vm/cc/IsolateReload_* tests we flip the GC flag on, which will
  // cause the isolate reload to do GCs before/after morphing, etc.
  FLAG_gc_during_reload = true;
  FLAG_force_evacuation = true;

  Dart_SourceFile* sourcefiles = nullptr;
  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();
}

Dart_Handle TestCase::TriggerReload(
    std::function<bool(IsolateGroup*, JSONStream*)> do_reload) {
  Thread* thread = Thread::Current();
  IsolateGroup* isolate_group = thread->isolate_group();
  JSONStream js;
  js.set_id_zone(thread->isolate()->EnsureDefaultServiceIdZone());
  bool success = false;
  {
    TransitionNativeToVM transition(thread);
    success = do_reload(isolate_group, &js);
    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_group->reload_context()->reload_aborted()) {
    TransitionNativeToVM transition(thread);
    result = Api::NewHandle(thread, isolate_group->program_reload_context()
                                        ->group_reload_context()
                                        ->error());
  } else {
    result = Dart_RootLibrary();
  }

  TransitionNativeToVM transition(thread);
  if (isolate_group->program_reload_context() != nullptr) {
    isolate_group->DeleteReloadContext();
  }

  return result;
}

Dart_Handle TestCase::TriggerReload(const char* root_script_url) {
  return TriggerReload([&](IsolateGroup* isolate_group, JSONStream* js) {
    return isolate_group->ReloadSources(js,
                                        /*force_reload=*/false, root_script_url,
                                        /*packages_url=*/nullptr,
                                        /*dont_delete_reload_context=*/true);
  });
}

Dart_Handle TestCase::TriggerReload(const uint8_t* kernel_buffer,
                                    intptr_t kernel_buffer_size) {
  return TriggerReload([&](IsolateGroup* isolate_group, JSONStream* js) {
    return isolate_group->ReloadKernel(js,
                                       /*force_reload=*/false, kernel_buffer,
                                       kernel_buffer_size,
                                       /*dont_delete_reload_context=*/true);
  });
}

Dart_Handle TestCase::ReloadTestScript(const char* script) {
  Dart_SourceFile* sourcefiles = nullptr;
  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 TriggerReload(/*kernel_buffer=*/nullptr, /*kernel_buffer_size=*/0);
}

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

#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);
  EXPECT_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()) {
    UNREACHABLE();
  } else {
    Dart_KernelCompilationResult compilation_result =
        KernelIsolate::CompileExpressionToKernel(
            /* platform_kernel= */ nullptr, /* platform_kernel_size= */ 0,
            expr.ToCString(), param_names, Array::empty_array(),
            Array::empty_array(), Array::empty_array(), Array::empty_array(),
            String::Handle(lib.url()).ToCString(),
            /* klass= */ nullptr,
            /* method= */ nullptr,
            /* token_pos= */ TokenPosition::kNoSource,
            /* script_uri= */ String::Handle(lib.url()).ToCString(),
            /* is_static= */ true);
    if (compilation_result.status != Dart_KernelCompilationStatus_Ok) {
      return Api::NewError("%s", compilation_result.error);
    }

    const ExternalTypedData& kernel_buffer =
        ExternalTypedData::Handle(ExternalTypedData::NewFinalizeWithFree(
            const_cast<uint8_t*>(compilation_result.kernel),
            compilation_result.kernel_size));

    val = lib.EvaluateCompiledExpression(kernel_buffer, Array::empty_array(),
                                         param_values,
                                         TypeArguments::null_type_arguments());
  }
  return Api::NewHandle(thread, val.ptr());
}

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

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

  // We make a dummy script so that exception objects can be composed for
  // assembler instructions that do runtime calls.
  const char* kDummyScript = "assembler_test_dummy_function() {}";
  const Script& script = Script::Handle(
      Script::New(function_name, String::Handle(String::New(kDummyScript))));
  const Library& lib = Library::Handle(Library::CoreLibrary());
  const Class& cls = Class::ZoneHandle(
      Class::New(lib, function_name, script, TokenPosition::kMinSource));
  const FunctionType& signature = FunctionType::ZoneHandle(FunctionType::New());
  Function& function = Function::ZoneHandle(Function::New(
      signature, function_name, UntaggedFunction::kRegularFunction, true, false,
      false, false, false, cls, TokenPosition::kMinSource));
  SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
  code_ = Code::FinalizeCodeAndNotify(function, nullptr, assembler_,
                                      Code::PoolAttachment::kAttachPool);
  code_.set_owner(function);
  code_.set_exception_handlers(Object::empty_exception_handlers());
#ifndef PRODUCT
  // Disassemble relative since code addresses are not stable from run to run.
  SetFlagScope<bool> sfs(&FLAG_disassemble_relative, true);
  uword start = code_.PayloadStart();
  uword end = start + assembler_->CodeSize();
#if defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
  Disassembler::SetExtensions(assembler_->extensions());
#endif
  if (FLAG_disassemble) {
    OS::PrintErr("Code for test '%s' {\n", name_);
    Disassembler::Disassemble(start, end);
    OS::PrintErr("}\n");
  }
  Disassembler::Disassemble(start, end, disassembly_, DISASSEMBLY_SIZE);
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
  // Blank out absolute addressing constants on ia32, since they are not stable
  // from run to run.
  // Blank out thread-relative offsets on x64 since they change when new fields
  // are added to thread object.
  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 defined(TARGET_ARCH_IA32)
      if (*p == '[' && *(p + 1) == '0' && *(p + 2) == 'x' && IsHex(*(p + 3)) &&
          IsHex(*(p + 4))) {
        p += 2;
        in_hex_constant = true;
      }
#endif  // defined(TARGET_ARCH_IA32)
#if defined(TARGET_ARCH_X64)
      if (*p == '[' && *(p + 1) == 't' && *(p + 2) == 'h' && *(p + 3) == 'r' &&
          *(p + 4) == '+' && *(p + 5) == '0' && *(p + 6) == 'x' &&
          IsHex(*(p + 7)) && IsHex(*(p + 8))) {
        p += 6;
        in_hex_constant = true;
      }
#endif  // defined(TARGET_ARCH_X64)
    }
  }
#endif  // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
#endif  // !PRODUCT
}

const Code& AssemblerTest::Generate(
    const char* name,
    const std::function<void(compiler::Assembler* assembler)>& generator) {
  compiler::ObjectPoolBuilder object_pool_builder;
  compiler::Assembler assembler(&object_pool_builder, /*far_branch_level=*/0);
  AssemblerTest test(name, &assembler, Thread::Current()->zone());
  assembler.Ret();
  test.Assemble();
  return test.code();
}

bool CompilerTest::TestCompileFunction(const Function& function) {
  Thread* thread = Thread::Current();
  ASSERT(thread != nullptr);
  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* postfix) {
  const char* pos = strstr(in, prefix);
  while (pos != nullptr) {
    // Copy up to pos into the output buffer.
    while (in < pos) {
      *out++ = *in++;
    }

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

void StripTokenPositions(char* buffer) {
  ElideJSONSubstring(",\"tokenPos\":", buffer, buffer, ",");
  ElideJSONSubstring(",\"endTokenPos\":", buffer, buffer, "}");
}

}  // namespace dart
