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

#include "bin/crypto.h"
#include "bin/directory.h"
#include "bin/extensions.h"
#include "bin/file.h"
#include "bin/io_buffer.h"
#include "bin/namespace.h"
#include "bin/platform.h"
#include "bin/utils.h"

#include "include/dart_api.h"
#include "include/dart_native_api.h"
#include "include/dart_tools_api.h"

#include "platform/assert.h"
#include "platform/globals.h"
#include "platform/memory_sanitizer.h"
#include "platform/utils.h"

// Return the error from the containing function if handle is in error handle.
#define RETURN_IF_ERROR(handle)                                                \
  {                                                                            \
    Dart_Handle __handle = handle;                                             \
    if (Dart_IsError((__handle))) {                                            \
      return __handle;                                                         \
    }                                                                          \
  }

namespace dart {
namespace bin {

const char* DartUtils::original_working_directory = NULL;
CommandLineOptions* DartUtils::url_mapping = NULL;
const char* const DartUtils::kDartScheme = "dart:";
const char* const DartUtils::kDartExtensionScheme = "dart-ext:";
const char* const DartUtils::kAsyncLibURL = "dart:async";
const char* const DartUtils::kBuiltinLibURL = "dart:_builtin";
const char* const DartUtils::kCoreLibURL = "dart:core";
const char* const DartUtils::kInternalLibURL = "dart:_internal";
const char* const DartUtils::kIsolateLibURL = "dart:isolate";
const char* const DartUtils::kHttpLibURL = "dart:_http";
const char* const DartUtils::kIOLibURL = "dart:io";
const char* const DartUtils::kIOLibPatchURL = "dart:io-patch";
const char* const DartUtils::kCLILibURL = "dart:cli";
const char* const DartUtils::kCLILibPatchURL = "dart:cli-patch";
const char* const DartUtils::kUriLibURL = "dart:uri";
const char* const DartUtils::kHttpScheme = "http:";
const char* const DartUtils::kVMServiceLibURL = "dart:vmservice";

MagicNumberData appjit_magic_number = {8, {0xdc, 0xdc, 0xf6, 0xf6, 0, 0, 0, 0}};
MagicNumberData snapshot_magic_number = {4, {0xf5, 0xf5, 0xdc, 0xdc}};
MagicNumberData kernel_magic_number = {4, {0x90, 0xab, 0xcd, 0xef}};
MagicNumberData gzip_magic_number = {2, {0x1f, 0x8b, 0, 0}};

static bool IsWindowsHost() {
#if defined(HOST_OS_WINDOWS)
  return true;
#else   // defined(HOST_OS_WINDOWS)
  return false;
#endif  // defined(HOST_OS_WINDOWS)
}

const char* DartUtils::MapLibraryUrl(const char* url_string) {
  ASSERT(url_mapping != NULL);
  // We need to check if the passed in url is found in the url_mapping array,
  // in that case use the mapped entry.
  intptr_t len = strlen(url_string);
  for (intptr_t idx = 0; idx < url_mapping->count(); idx++) {
    const char* url_name = url_mapping->GetArgument(idx);
    if (!strncmp(url_string, url_name, len) && (url_name[len] == ',')) {
      const char* url_mapped_name = url_name + len + 1;
      if (strlen(url_mapped_name) != 0) {
        return url_mapped_name;  // Found a mapping for this URL.
      }
    }
  }
  return NULL;  // Did not find a mapping for this URL.
}

int64_t DartUtils::GetIntegerValue(Dart_Handle value_obj) {
  int64_t value = 0;
  Dart_Handle result = Dart_IntegerToInt64(value_obj, &value);
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
  return value;
}

int64_t DartUtils::GetInt64ValueCheckRange(Dart_Handle value_obj,
                                           int64_t lower,
                                           int64_t upper) {
  int64_t value = DartUtils::GetIntegerValue(value_obj);
  if (value < lower || upper < value) {
    Dart_PropagateError(Dart_NewApiError("Value outside expected range"));
  }
  return value;
}

intptr_t DartUtils::GetIntptrValue(Dart_Handle value_obj) {
  int64_t value = 0;
  Dart_Handle result = Dart_IntegerToInt64(value_obj, &value);
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
  if (value < kIntptrMin || kIntptrMax < value) {
    Dart_PropagateError(Dart_NewApiError("Value outside intptr_t range"));
  }
  return static_cast<intptr_t>(value);
}

bool DartUtils::GetInt64Value(Dart_Handle value_obj, int64_t* value) {
  bool valid = Dart_IsInteger(value_obj);
  if (valid) {
    Dart_Handle result = Dart_IntegerFitsIntoInt64(value_obj, &valid);
    if (Dart_IsError(result)) {
      Dart_PropagateError(result);
    }
  }
  if (!valid) return false;
  Dart_Handle result = Dart_IntegerToInt64(value_obj, value);
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
  return true;
}

const char* DartUtils::GetStringValue(Dart_Handle str_obj) {
  const char* cstring = NULL;
  Dart_Handle result = Dart_StringToCString(str_obj, &cstring);
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
  return cstring;
}

bool DartUtils::GetBooleanValue(Dart_Handle bool_obj) {
  bool value = false;
  Dart_Handle result = Dart_BooleanValue(bool_obj, &value);
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
  return value;
}

bool DartUtils::GetNativeBooleanArgument(Dart_NativeArguments args,
                                         intptr_t index) {
  bool value = false;
  Dart_Handle result = Dart_GetNativeBooleanArgument(args, index, &value);
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
  return value;
}

int64_t DartUtils::GetNativeIntegerArgument(Dart_NativeArguments args,
                                            intptr_t index) {
  int64_t value = 0;
  Dart_Handle result = Dart_GetNativeIntegerArgument(args, index, &value);
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
  return value;
}

intptr_t DartUtils::GetNativeIntptrArgument(Dart_NativeArguments args,
                                            intptr_t index) {
  int64_t value = GetNativeIntegerArgument(args, index);
  if (value < kIntptrMin || kIntptrMax < value) {
    Dart_PropagateError(Dart_NewApiError("Value outside intptr_t range"));
  }
  return static_cast<intptr_t>(value);
}

const char* DartUtils::GetNativeStringArgument(Dart_NativeArguments args,
                                               intptr_t index) {
  char* tmp = NULL;
  Dart_Handle result =
      Dart_GetNativeStringArgument(args, index, reinterpret_cast<void**>(&tmp));
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
  if (tmp != NULL) {
    return tmp;
  }
  const char* cstring = NULL;
  result = Dart_StringToCString(result, &cstring);
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
  ASSERT(cstring != NULL);
  return cstring;
}

Dart_Handle DartUtils::SetIntegerField(Dart_Handle handle,
                                       const char* name,
                                       int64_t val) {
  return Dart_SetField(handle, NewString(name), Dart_NewInteger(val));
}

Dart_Handle DartUtils::SetStringField(Dart_Handle handle,
                                      const char* name,
                                      const char* val) {
  return Dart_SetField(handle, NewString(name), NewString(val));
}

bool DartUtils::IsDartSchemeURL(const char* url_name) {
  static const intptr_t kDartSchemeLen = strlen(kDartScheme);
  // If the URL starts with "dart:" then it is considered as a special
  // library URL which is handled differently from other URLs.
  return (strncmp(url_name, kDartScheme, kDartSchemeLen) == 0);
}

bool DartUtils::IsHttpSchemeURL(const char* url_name) {
  static const intptr_t kHttpSchemeLen = strlen(kHttpScheme);
  return (strncmp(url_name, kHttpScheme, kHttpSchemeLen) == 0);
}

bool DartUtils::IsDartExtensionSchemeURL(const char* url_name) {
  static const intptr_t kDartExtensionSchemeLen = strlen(kDartExtensionScheme);
  // If the URL starts with "dartext:" then it is considered as a special
  // extension library URL which is handled differently from other URLs.
  return (strncmp(url_name, kDartExtensionScheme, kDartExtensionSchemeLen) ==
          0);
}

bool DartUtils::IsDartIOLibURL(const char* url_name) {
  return (strcmp(url_name, kIOLibURL) == 0);
}

bool DartUtils::IsDartCLILibURL(const char* url_name) {
  return (strcmp(url_name, kCLILibURL) == 0);
}

bool DartUtils::IsDartHttpLibURL(const char* url_name) {
  return (strcmp(url_name, kHttpLibURL) == 0);
}

bool DartUtils::IsDartBuiltinLibURL(const char* url_name) {
  return (strcmp(url_name, kBuiltinLibURL) == 0);
}

const char* DartUtils::RemoveScheme(const char* url) {
  const char* colon = strchr(url, ':');
  if (colon == NULL) {
    return url;
  } else {
    return colon + 1;
  }
}

char* DartUtils::DirName(const char* url) {
  const char* slash = strrchr(url, File::PathSeparator()[0]);
  if (slash == NULL) {
    return strdup(url);
  } else {
    return Utils::StrNDup(url, slash - url + 1);
  }
}

void* DartUtils::OpenFile(const char* name, bool write) {
  File* file =
      File::Open(NULL, name, write ? File::kWriteTruncate : File::kRead);
  return reinterpret_cast<void*>(file);
}

void* DartUtils::OpenFileUri(const char* uri, bool write) {
  File* file =
      File::OpenUri(NULL, uri, write ? File::kWriteTruncate : File::kRead);
  return reinterpret_cast<void*>(file);
}

void DartUtils::ReadFile(uint8_t** data, intptr_t* len, void* stream) {
  ASSERT(data != NULL);
  ASSERT(len != NULL);
  ASSERT(stream != NULL);
  File* file_stream = reinterpret_cast<File*>(stream);
  int64_t file_len = file_stream->Length();
  if ((file_len < 0) || (file_len > kIntptrMax)) {
    *data = NULL;
    *len = -1;  // Indicates read was not successful.
    return;
  }
  *len = static_cast<intptr_t>(file_len);
  *data = reinterpret_cast<uint8_t*>(malloc(*len));
  if (*data == NULL) {
    OUT_OF_MEMORY();
  }
  if (!file_stream->ReadFully(*data, *len)) {
    free(*data);
    *data = NULL;
    *len = -1;  // Indicates read was not successful.
    return;
  }
}

void DartUtils::WriteFile(const void* buffer,
                          intptr_t num_bytes,
                          void* stream) {
  ASSERT(stream != NULL);
  File* file_stream = reinterpret_cast<File*>(stream);
  bool bytes_written = file_stream->WriteFully(buffer, num_bytes);
  ASSERT(bytes_written);
}

void DartUtils::CloseFile(void* stream) {
  File* file = reinterpret_cast<File*>(stream);
  file->Release();
}

bool DartUtils::EntropySource(uint8_t* buffer, intptr_t length) {
  return Crypto::GetRandomBytes(length, buffer);
}

static Dart_Handle SingleArgDart_Invoke(Dart_Handle lib,
                                        const char* method,
                                        Dart_Handle arg) {
  const int kNumArgs = 1;
  Dart_Handle dart_args[kNumArgs];
  dart_args[0] = arg;
  return Dart_Invoke(lib, DartUtils::NewString(method), kNumArgs, dart_args);
}

// TODO(iposva): Allocate from the zone instead of leaking error string
// here. On the other hand the binary is about to exit anyway.
#define SET_ERROR_MSG(error_msg, format, ...)                                  \
  intptr_t len = snprintf(NULL, 0, format, __VA_ARGS__);                       \
  char* msg = reinterpret_cast<char*>(malloc(len + 1));                        \
  snprintf(msg, len + 1, format, __VA_ARGS__);                                 \
  *error_msg = msg

static uint8_t* ReadFileFully(const char* filename,
                              intptr_t* file_len,
                              const char** error_msg) {
  *file_len = -1;
  void* stream = DartUtils::OpenFile(filename, false);
  if (stream == NULL) {
    SET_ERROR_MSG(error_msg, "Unable to open file: %s", filename);
    return NULL;
  }
  uint8_t* text_buffer = NULL;
  DartUtils::ReadFile(&text_buffer, file_len, stream);
  if (text_buffer == NULL || *file_len == -1) {
    *error_msg = "Unable to read file contents";
    text_buffer = NULL;
  }
  DartUtils::CloseFile(stream);
  return text_buffer;
}

Dart_Handle DartUtils::ReadStringFromFile(const char* filename) {
  const char* error_msg = NULL;
  intptr_t len;
  uint8_t* text_buffer = ReadFileFully(filename, &len, &error_msg);
  if (text_buffer == NULL) {
    return Dart_NewApiError(error_msg);
  }
  Dart_Handle str = Dart_NewStringFromUTF8(text_buffer, len);
  free(text_buffer);
  return str;
}

Dart_Handle DartUtils::MakeUint8Array(const uint8_t* buffer, intptr_t len) {
  Dart_Handle array = Dart_NewTypedData(Dart_TypedData_kUint8, len);
  RETURN_IF_ERROR(array);
  {
    Dart_TypedData_Type td_type;
    void* td_data;
    intptr_t td_len;
    Dart_Handle result =
        Dart_TypedDataAcquireData(array, &td_type, &td_data, &td_len);
    RETURN_IF_ERROR(result);
    ASSERT(td_type == Dart_TypedData_kUint8);
    ASSERT(td_len == len);
    ASSERT(td_data != NULL);
    memmove(td_data, buffer, td_len);
    result = Dart_TypedDataReleaseData(array);
    RETURN_IF_ERROR(result);
  }
  return array;
}

Dart_Handle DartUtils::SetWorkingDirectory() {
  Dart_Handle directory = NewString(original_working_directory);
  return SingleArgDart_Invoke(LookupBuiltinLib(), "_setWorkingDirectory",
                              directory);
}

Dart_Handle DartUtils::ResolveUriInWorkingDirectory(Dart_Handle script_uri) {
  const int kNumArgs = 1;
  Dart_Handle dart_args[kNumArgs];
  dart_args[0] = script_uri;
  return Dart_Invoke(DartUtils::LookupBuiltinLib(),
                     NewString("_resolveInWorkingDirectory"), kNumArgs,
                     dart_args);
}

Dart_Handle DartUtils::LibraryFilePath(Dart_Handle library_uri) {
  const int kNumArgs = 1;
  Dart_Handle dart_args[kNumArgs];
  dart_args[0] = library_uri;
  return Dart_Invoke(DartUtils::LookupBuiltinLib(),
                     NewString("_libraryFilePath"), kNumArgs, dart_args);
}

Dart_Handle DartUtils::ResolveScript(Dart_Handle url) {
  const int kNumArgs = 1;
  Dart_Handle dart_args[kNumArgs];
  dart_args[0] = url;
  return Dart_Invoke(DartUtils::LookupBuiltinLib(),
                     NewString("_resolveScriptUri"), kNumArgs, dart_args);
}

static bool CheckMagicNumber(const uint8_t* buffer,
                             intptr_t buffer_length,
                             const MagicNumberData& magic_number) {
  if ((buffer_length >= magic_number.length)) {
    return memcmp(buffer, magic_number.bytes, magic_number.length) == 0;
  }
  return false;
}

DartUtils::MagicNumber DartUtils::SniffForMagicNumber(const char* filename) {
  MagicNumber magic_number = DartUtils::kUnknownMagicNumber;
  if (File::GetType(NULL, filename, true) == File::kIsFile) {
    File* file = File::Open(NULL, filename, File::kRead);
    if (file != NULL) {
      RefCntReleaseScope<File> rs(file);
      intptr_t max_magic_length = 0;
      max_magic_length =
          Utils::Maximum(max_magic_length, snapshot_magic_number.length);
      max_magic_length =
          Utils::Maximum(max_magic_length, appjit_magic_number.length);
      max_magic_length =
          Utils::Maximum(max_magic_length, kernel_magic_number.length);
      max_magic_length =
          Utils::Maximum(max_magic_length, gzip_magic_number.length);
      ASSERT(max_magic_length <= 8);
      uint8_t header[8];
      if (file->ReadFully(&header, max_magic_length)) {
        magic_number = DartUtils::SniffForMagicNumber(header, sizeof(header));
      }
    }
  }
  return magic_number;
}

DartUtils::MagicNumber DartUtils::SniffForMagicNumber(const uint8_t* buffer,
                                                      intptr_t buffer_length) {
  if (CheckMagicNumber(buffer, buffer_length, snapshot_magic_number)) {
    return kSnapshotMagicNumber;
  }

  if (CheckMagicNumber(buffer, buffer_length, appjit_magic_number)) {
    return kAppJITMagicNumber;
  }

  if (CheckMagicNumber(buffer, buffer_length, kernel_magic_number)) {
    return kKernelMagicNumber;
  }

  if (CheckMagicNumber(buffer, buffer_length, gzip_magic_number)) {
    return kGzipMagicNumber;
  }

  if (CheckMagicNumber(buffer, buffer_length, gzip_magic_number)) {
    return kGzipMagicNumber;
  }

  return kUnknownMagicNumber;
}

Dart_Handle DartUtils::PrepareBuiltinLibrary(Dart_Handle builtin_lib,
                                             Dart_Handle internal_lib,
                                             bool is_service_isolate,
                                             bool trace_loading) {
  // Setup the internal library's 'internalPrint' function.
  Dart_Handle print =
      Dart_Invoke(builtin_lib, NewString("_getPrintClosure"), 0, NULL);
  RETURN_IF_ERROR(print);
  Dart_Handle result =
      Dart_SetField(internal_lib, NewString("_printClosure"), print);
  RETURN_IF_ERROR(result);

  if (!is_service_isolate) {
    if (IsWindowsHost()) {
      result = Dart_SetField(builtin_lib, NewString("_isWindows"), Dart_True());
      RETURN_IF_ERROR(result);
    }
    if (trace_loading) {
      result =
          Dart_SetField(builtin_lib, NewString("_traceLoading"), Dart_True());
      RETURN_IF_ERROR(result);
    }
    // Set current working directory.
    result = SetWorkingDirectory();
    RETURN_IF_ERROR(result);
  }
  return Dart_True();
}

Dart_Handle DartUtils::PrepareCoreLibrary(Dart_Handle core_lib,
                                          Dart_Handle io_lib,
                                          bool is_service_isolate) {
  if (!is_service_isolate) {
    // Setup the 'Uri.base' getter in dart:core.
    Dart_Handle uri_base =
        Dart_Invoke(io_lib, NewString("_getUriBaseClosure"), 0, NULL);
    RETURN_IF_ERROR(uri_base);
    Dart_Handle result =
        Dart_SetField(core_lib, NewString("_uriBaseClosure"), uri_base);
    RETURN_IF_ERROR(result);
  }
  return Dart_True();
}

Dart_Handle DartUtils::PrepareAsyncLibrary(Dart_Handle async_lib,
                                           Dart_Handle isolate_lib) {
  Dart_Handle schedule_immediate_closure = Dart_Invoke(
      isolate_lib, NewString("_getIsolateScheduleImmediateClosure"), 0, NULL);
  RETURN_IF_ERROR(schedule_immediate_closure);
  Dart_Handle args[1];
  args[0] = schedule_immediate_closure;
  return Dart_Invoke(async_lib, NewString("_setScheduleImmediateClosure"), 1,
                     args);
}

Dart_Handle DartUtils::PrepareIOLibrary(Dart_Handle io_lib) {
  return Dart_Invoke(io_lib, NewString("_setupHooks"), 0, NULL);
}

Dart_Handle DartUtils::PrepareIsolateLibrary(Dart_Handle isolate_lib) {
  return Dart_Invoke(isolate_lib, NewString("_setupHooks"), 0, NULL);
}

Dart_Handle DartUtils::PrepareCLILibrary(Dart_Handle cli_lib) {
  Dart_Handle wait_for_event_handle =
      Dart_Invoke(cli_lib, NewString("_getWaitForEvent"), 0, NULL);
  RETURN_IF_ERROR(wait_for_event_handle);
  return Dart_SetField(cli_lib, NewString("_waitForEventClosure"),
                       wait_for_event_handle);
}

Dart_Handle DartUtils::SetupServiceLoadPort() {
  // Wait for the service isolate to initialize the load port.
  Dart_Port load_port = Dart_ServiceWaitForLoadPort();
  if (load_port == ILLEGAL_PORT) {
    return Dart_NewUnhandledExceptionError(
        NewDartUnsupportedError("Service did not return load port."));
  }
  return Builtin::SetLoadPort(load_port);
}

Dart_Handle DartUtils::SetupPackageRoot(const char* package_root,
                                        const char* packages_config) {
  Dart_Handle result = Dart_Null();

  // Set up package root if specified.
  if (package_root != NULL) {
    ASSERT(packages_config == NULL);
    result = NewString(package_root);
    RETURN_IF_ERROR(result);
    const int kNumArgs = 1;
    Dart_Handle dart_args[kNumArgs];
    dart_args[0] = result;
    result = Dart_Invoke(DartUtils::LookupBuiltinLib(),
                         NewString("_setPackageRoot"), kNumArgs, dart_args);
  } else if (packages_config != NULL) {
    result = NewString(packages_config);
    RETURN_IF_ERROR(result);
    const int kNumArgs = 1;
    Dart_Handle dart_args[kNumArgs];
    dart_args[0] = result;
    result = Dart_Invoke(DartUtils::LookupBuiltinLib(),
                         NewString("_setPackagesMap"), kNumArgs, dart_args);
  }
  return result;
}

Dart_Handle DartUtils::PrepareForScriptLoading(bool is_service_isolate,
                                               bool trace_loading) {
  // First ensure all required libraries are available.
  Dart_Handle url = NewString(kCoreLibURL);
  RETURN_IF_ERROR(url);
  Dart_Handle core_lib = Dart_LookupLibrary(url);
  RETURN_IF_ERROR(core_lib);
  url = NewString(kAsyncLibURL);
  RETURN_IF_ERROR(url);
  Dart_Handle async_lib = Dart_LookupLibrary(url);
  RETURN_IF_ERROR(async_lib);
  url = NewString(kIsolateLibURL);
  RETURN_IF_ERROR(url);
  Dart_Handle isolate_lib = Dart_LookupLibrary(url);
  RETURN_IF_ERROR(isolate_lib);
  url = NewString(kInternalLibURL);
  RETURN_IF_ERROR(url);
  Dart_Handle internal_lib = Dart_LookupLibrary(url);
  RETURN_IF_ERROR(internal_lib);
  Dart_Handle builtin_lib =
      Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
  RETURN_IF_ERROR(builtin_lib);
  Builtin::SetNativeResolver(Builtin::kBuiltinLibrary);
  Dart_Handle io_lib = Builtin::LoadAndCheckLibrary(Builtin::kIOLibrary);
  RETURN_IF_ERROR(io_lib);
  Builtin::SetNativeResolver(Builtin::kIOLibrary);
  Dart_Handle cli_lib = Builtin::LoadAndCheckLibrary(Builtin::kCLILibrary);
  RETURN_IF_ERROR(cli_lib);
  Builtin::SetNativeResolver(Builtin::kCLILibrary);

  // We need to ensure that all the scripts loaded so far are finalized
  // as we are about to invoke some Dart code below to setup closures.
  Dart_Handle result = Dart_FinalizeLoading(false);
  RETURN_IF_ERROR(result);

  result = PrepareBuiltinLibrary(builtin_lib, internal_lib, is_service_isolate,
                                 trace_loading);
  RETURN_IF_ERROR(result);

  RETURN_IF_ERROR(PrepareAsyncLibrary(async_lib, isolate_lib));
  RETURN_IF_ERROR(PrepareCoreLibrary(core_lib, io_lib, is_service_isolate));
  RETURN_IF_ERROR(PrepareIsolateLibrary(isolate_lib));
  RETURN_IF_ERROR(PrepareIOLibrary(io_lib));
  RETURN_IF_ERROR(PrepareCLILibrary(cli_lib));
  return result;
}

Dart_Handle DartUtils::SetupIOLibrary(const char* namespc_path,
                                      const char* script_uri,
                                      bool disable_exit) {
  Dart_Handle io_lib_url = NewString(kIOLibURL);
  RETURN_IF_ERROR(io_lib_url);
  Dart_Handle io_lib = Dart_LookupLibrary(io_lib_url);
  RETURN_IF_ERROR(io_lib);

  if (namespc_path != NULL) {
    Dart_Handle namespc_type = GetDartType(DartUtils::kIOLibURL, "_Namespace");
    RETURN_IF_ERROR(namespc_type);
    Dart_Handle args[1];
    args[0] = NewString(namespc_path);
    RETURN_IF_ERROR(args[0]);
    Dart_Handle result =
        Dart_Invoke(namespc_type, NewString("_setupNamespace"), 1, args);
    RETURN_IF_ERROR(result);
  }

  if (disable_exit) {
    Dart_Handle embedder_config_type =
        GetDartType(DartUtils::kIOLibURL, "_EmbedderConfig");
    RETURN_IF_ERROR(embedder_config_type);
    Dart_Handle result = Dart_SetField(embedder_config_type,
                                       NewString("_mayExit"), Dart_False());
    RETURN_IF_ERROR(result);
  }

  Dart_Handle platform_type = GetDartType(DartUtils::kIOLibURL, "_Platform");
  RETURN_IF_ERROR(platform_type);
  Dart_Handle script_name = NewString("_nativeScript");
  RETURN_IF_ERROR(script_name);
  Dart_Handle dart_script = NewString(script_uri);
  RETURN_IF_ERROR(dart_script);
  Dart_Handle set_script_name =
      Dart_SetField(platform_type, script_name, dart_script);
  RETURN_IF_ERROR(set_script_name);
  return Dart_Null();
}

bool DartUtils::PostNull(Dart_Port port_id) {
  // Post a message with just the null object.
  return Dart_PostCObject(port_id, CObject::Null()->AsApiCObject());
}

bool DartUtils::PostInt32(Dart_Port port_id, int32_t value) {
  // Post a message with the integer value.
  int32_t min = 0xc0000000;  // -1073741824
  int32_t max = 0x3fffffff;  // 1073741823
  ASSERT(min <= value && value < max);
  Dart_CObject object;
  object.type = Dart_CObject_kInt32;
  object.value.as_int32 = value;
  return Dart_PostCObject(port_id, &object);
}

bool DartUtils::PostInt64(Dart_Port port_id, int64_t value) {
  // Post a message with the integer value.
  Dart_CObject object;
  object.type = Dart_CObject_kInt64;
  object.value.as_int64 = value;
  return Dart_PostCObject(port_id, &object);
}

Dart_Handle DartUtils::GetDartType(const char* library_url,
                                   const char* class_name) {
  return Dart_GetType(Dart_LookupLibrary(NewString(library_url)),
                      NewString(class_name), 0, NULL);
}

Dart_Handle DartUtils::NewDartOSError() {
  // Extract the current OS error.
  OSError os_error;
  return NewDartOSError(&os_error);
}

Dart_Handle DartUtils::NewDartOSError(OSError* os_error) {
  // Create a dart:io OSError object with the information retrieved from the OS.
  Dart_Handle type = GetDartType(kIOLibURL, "OSError");
  ASSERT(!Dart_IsError(type));
  Dart_Handle args[2];
  args[0] = NewString(os_error->message());
  args[1] = Dart_NewInteger(os_error->code());
  return Dart_New(type, Dart_Null(), 2, args);
}

Dart_Handle DartUtils::NewDartExceptionWithOSError(const char* library_url,
                                                   const char* exception_name,
                                                   const char* message,
                                                   Dart_Handle os_error) {
  // Create a Dart Exception object with a message and an OSError.
  Dart_Handle type = GetDartType(library_url, exception_name);
  ASSERT(!Dart_IsError(type));
  Dart_Handle args[2];
  args[0] = NewString(message);
  args[1] = os_error;
  return Dart_New(type, Dart_Null(), 2, args);
}

Dart_Handle DartUtils::NewDartExceptionWithMessage(const char* library_url,
                                                   const char* exception_name,
                                                   const char* message) {
  // Create a Dart Exception object with a message.
  Dart_Handle type = GetDartType(library_url, exception_name);
  ASSERT(!Dart_IsError(type));
  if (message != NULL) {
    Dart_Handle args[1];
    args[0] = NewString(message);
    return Dart_New(type, Dart_Null(), 1, args);
  } else {
    return Dart_New(type, Dart_Null(), 0, NULL);
  }
}

Dart_Handle DartUtils::NewDartArgumentError(const char* message) {
  return NewDartExceptionWithMessage(kCoreLibURL, "ArgumentError", message);
}

Dart_Handle DartUtils::NewDartUnsupportedError(const char* message) {
  return NewDartExceptionWithMessage(kCoreLibURL, "UnsupportedError", message);
}

Dart_Handle DartUtils::NewDartIOException(const char* exception_name,
                                          const char* message,
                                          Dart_Handle os_error) {
  // Create a dart:io exception object of the given type.
  return NewDartExceptionWithOSError(kIOLibURL, exception_name, message,
                                     os_error);
}

Dart_Handle DartUtils::NewError(const char* format, ...) {
  va_list args;
  va_start(args, format);
  intptr_t len = vsnprintf(NULL, 0, format, args);
  va_end(args);

  char* buffer = reinterpret_cast<char*>(Dart_ScopeAllocate(len + 1));
  MSAN_UNPOISON(buffer, (len + 1));
  va_list args2;
  va_start(args2, format);
  vsnprintf(buffer, (len + 1), format, args2);
  va_end(args2);

  return Dart_NewApiError(buffer);
}

Dart_Handle DartUtils::NewInternalError(const char* message) {
  return NewDartExceptionWithMessage(kCoreLibURL, "_InternalError", message);
}

bool DartUtils::SetOriginalWorkingDirectory() {
  original_working_directory = Directory::CurrentNoScope();
  return original_working_directory != NULL;
}

Dart_Handle DartUtils::GetCanonicalizableWorkingDirectory() {
  const char* str = DartUtils::original_working_directory;
  intptr_t len = strlen(str);
  if ((str[len] == '/') || (IsWindowsHost() && str[len] == '\\')) {
    return Dart_NewStringFromCString(str);
  }
  char* new_str = reinterpret_cast<char*>(Dart_ScopeAllocate(len + 2));
  snprintf(new_str, (len + 2), "%s%s", str, File::PathSeparator());
  return Dart_NewStringFromCString(new_str);
}

// Statically allocated Dart_CObject instances for immutable
// objects. As these will be used by different threads the use of
// these depends on the fact that the marking internally in the
// Dart_CObject structure is not marking simple value objects.
Dart_CObject CObject::api_null_ = {Dart_CObject_kNull, {0}};
Dart_CObject CObject::api_true_ = {Dart_CObject_kBool, {true}};
Dart_CObject CObject::api_false_ = {Dart_CObject_kBool, {false}};
CObject CObject::null_ = CObject(&api_null_);
CObject CObject::true_ = CObject(&api_true_);
CObject CObject::false_ = CObject(&api_false_);

CObject* CObject::Null() {
  return &null_;
}

CObject* CObject::True() {
  return &true_;
}

CObject* CObject::False() {
  return &false_;
}

CObject* CObject::Bool(bool value) {
  return value ? &true_ : &false_;
}

Dart_CObject* CObject::New(Dart_CObject_Type type, int additional_bytes) {
  Dart_CObject* cobject = reinterpret_cast<Dart_CObject*>(
      Dart_ScopeAllocate(sizeof(Dart_CObject) + additional_bytes));
  cobject->type = type;
  return cobject;
}

Dart_CObject* CObject::NewInt32(int32_t value) {
  Dart_CObject* cobject = New(Dart_CObject_kInt32);
  cobject->value.as_int32 = value;
  return cobject;
}

Dart_CObject* CObject::NewInt64(int64_t value) {
  Dart_CObject* cobject = New(Dart_CObject_kInt64);
  cobject->value.as_int64 = value;
  return cobject;
}

Dart_CObject* CObject::NewIntptr(intptr_t value) {
  // Pointer values passed as intptr_t are always send as int64_t.
  Dart_CObject* cobject = New(Dart_CObject_kInt64);
  cobject->value.as_int64 = value;
  return cobject;
}

Dart_CObject* CObject::NewDouble(double value) {
  Dart_CObject* cobject = New(Dart_CObject_kDouble);
  cobject->value.as_double = value;
  return cobject;
}

Dart_CObject* CObject::NewString(intptr_t length) {
  Dart_CObject* cobject = New(Dart_CObject_kString, length + 1);
  cobject->value.as_string = reinterpret_cast<char*>(cobject + 1);
  return cobject;
}

Dart_CObject* CObject::NewString(const char* str) {
  intptr_t length = strlen(str);
  Dart_CObject* cobject = NewString(length);
  memmove(cobject->value.as_string, str, length + 1);
  return cobject;
}

Dart_CObject* CObject::NewArray(intptr_t length) {
  Dart_CObject* cobject =
      New(Dart_CObject_kArray, length * sizeof(Dart_CObject*));  // NOLINT
  cobject->value.as_array.length = length;
  cobject->value.as_array.values =
      reinterpret_cast<Dart_CObject**>(cobject + 1);
  return cobject;
}

Dart_CObject* CObject::NewUint8Array(intptr_t length) {
  Dart_CObject* cobject = New(Dart_CObject_kTypedData, length);
  cobject->value.as_typed_data.type = Dart_TypedData_kUint8;
  cobject->value.as_typed_data.length = length;
  cobject->value.as_typed_data.values = reinterpret_cast<uint8_t*>(cobject + 1);
  return cobject;
}

Dart_CObject* CObject::NewUint32Array(intptr_t length) {
  Dart_CObject* cobject = New(Dart_CObject_kTypedData, 4 * length);
  cobject->value.as_typed_data.type = Dart_TypedData_kUint32;
  cobject->value.as_typed_data.length = length;
  cobject->value.as_typed_data.values = reinterpret_cast<uint8_t*>(cobject + 1);
  return cobject;
}

Dart_CObject* CObject::NewExternalUint8Array(
    intptr_t length,
    uint8_t* data,
    void* peer,
    Dart_WeakPersistentHandleFinalizer callback) {
  Dart_CObject* cobject = New(Dart_CObject_kExternalTypedData);
  cobject->value.as_external_typed_data.type = Dart_TypedData_kUint8;
  cobject->value.as_external_typed_data.length = length;
  cobject->value.as_external_typed_data.data = data;
  cobject->value.as_external_typed_data.peer = peer;
  cobject->value.as_external_typed_data.callback = callback;
  return cobject;
}

Dart_CObject* CObject::NewIOBuffer(int64_t length) {
  // Make sure that we do not have an integer overflow here. Actual check
  // against max elements will be done at the time of writing, as the constant
  // is not part of the public API.
  if ((length < 0) || (length > kIntptrMax)) {
    return NULL;
  }
  uint8_t* data = IOBuffer::Allocate(static_cast<intptr_t>(length));
  if (data == NULL) {
    return NULL;
  }
  return NewExternalUint8Array(static_cast<intptr_t>(length), data, data,
                               IOBuffer::Finalizer);
}

void CObject::FreeIOBufferData(Dart_CObject* cobject) {
  ASSERT(cobject->type == Dart_CObject_kExternalTypedData);
  cobject->value.as_external_typed_data.callback(
      NULL, NULL, cobject->value.as_external_typed_data.peer);
  cobject->value.as_external_typed_data.data = NULL;
}

CObject* CObject::IllegalArgumentError() {
  CObjectArray* result = new CObjectArray(CObject::NewArray(1));
  result->SetAt(0, new CObjectInt32(CObject::NewInt32(kArgumentError)));
  return result;
}

CObject* CObject::FileClosedError() {
  CObjectArray* result = new CObjectArray(CObject::NewArray(1));
  result->SetAt(0, new CObjectInt32(CObject::NewInt32(kFileClosedError)));
  return result;
}

CObject* CObject::NewOSError() {
  OSError os_error;
  return NewOSError(&os_error);
}

CObject* CObject::NewOSError(OSError* os_error) {
  CObject* error_message =
      new CObjectString(CObject::NewString(os_error->message()));
  CObjectArray* result = new CObjectArray(CObject::NewArray(3));
  result->SetAt(0, new CObjectInt32(CObject::NewInt32(kOSError)));
  result->SetAt(1, new CObjectInt32(CObject::NewInt32(os_error->code())));
  result->SetAt(2, error_message);
  return result;
}

}  // namespace bin
}  // namespace dart
