blob: ed74804f50d6247592fe007c9bda7a197568e80d [file]
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "iree/base/api.h"
#include <cstdlib>
#include <cstring>
#include <string>
#include "iree/base/api_util.h"
#include "iree/base/file_mapping.h"
#include "iree/base/init.h"
#include "iree/base/tracing.h"
namespace iree {
//===----------------------------------------------------------------------===//
// iree_status_t
//===----------------------------------------------------------------------===//
IREE_API_EXPORT const char* IREE_API_CALL
iree_status_code_string(iree_status_code_t code) {
switch (code) {
case IREE_STATUS_OK:
return "OK";
case IREE_STATUS_CANCELLED:
return "CANCELLED";
case IREE_STATUS_UNKNOWN:
return "UNKNOWN";
case IREE_STATUS_INVALID_ARGUMENT:
return "INVALID_ARGUMENT";
case IREE_STATUS_DEADLINE_EXCEEDED:
return "DEADLINE_EXCEEDED";
case IREE_STATUS_NOT_FOUND:
return "NOT_FOUND";
case IREE_STATUS_ALREADY_EXISTS:
return "ALREADY_EXISTS";
case IREE_STATUS_PERMISSION_DENIED:
return "PERMISSION_DENIED";
case IREE_STATUS_UNAUTHENTICATED:
return "UNAUTHENTICATED";
case IREE_STATUS_RESOURCE_EXHAUSTED:
return "RESOURCE_EXHAUSTED";
case IREE_STATUS_FAILED_PRECONDITION:
return "FAILED_PRECONDITION";
case IREE_STATUS_ABORTED:
return "ABORTED";
case IREE_STATUS_OUT_OF_RANGE:
return "OUT_OF_RANGE";
case IREE_STATUS_UNIMPLEMENTED:
return "UNIMPLEMENTED";
case IREE_STATUS_INTERNAL:
return "INTERNAL";
case IREE_STATUS_UNAVAILABLE:
return "UNAVAILABLE";
case IREE_STATUS_DATA_LOSS:
return "DATA_LOSS";
default:
return "";
}
}
//===----------------------------------------------------------------------===//
// IREE Core API
//===----------------------------------------------------------------------===//
IREE_API_EXPORT iree_status_t IREE_API_CALL
iree_api_version_check(iree_api_version_t expected_version,
iree_api_version_t* out_actual_version) {
iree_api_version_t actual_version = IREE_API_VERSION_0;
*out_actual_version = actual_version;
return expected_version == actual_version ? IREE_STATUS_OK
: IREE_STATUS_OUT_OF_RANGE;
}
IREE_API_EXPORT iree_status_t IREE_API_CALL iree_api_init(int* argc,
char*** argv) {
InitializeEnvironment(argc, argv);
return IREE_STATUS_OK;
}
//===----------------------------------------------------------------------===//
// iree_allocator_t
//===----------------------------------------------------------------------===//
IREE_API_EXPORT iree_status_t IREE_API_CALL iree_allocator_malloc(
iree_allocator_t allocator, iree_host_size_t byte_length, void** out_ptr) {
if (!allocator.alloc) return IREE_STATUS_INVALID_ARGUMENT;
return allocator.alloc(allocator.self, IREE_ALLOCATION_MODE_ZERO_CONTENTS,
byte_length, out_ptr);
}
IREE_API_EXPORT iree_status_t IREE_API_CALL iree_allocator_realloc(
iree_allocator_t allocator, iree_host_size_t byte_length, void** out_ptr) {
if (!allocator.alloc) return IREE_STATUS_INVALID_ARGUMENT;
return allocator.alloc(allocator.self,
IREE_ALLOCATION_MODE_TRY_REUSE_EXISTING, byte_length,
out_ptr);
}
IREE_API_EXPORT void IREE_API_CALL
iree_allocator_free(iree_allocator_t allocator, void* ptr) {
if (ptr && allocator.free) {
return allocator.free(allocator.self, ptr);
}
}
IREE_API_EXPORT iree_status_t IREE_API_CALL
iree_allocator_system_allocate(void* self, iree_allocation_mode_t mode,
iree_host_size_t byte_length, void** out_ptr) {
IREE_TRACE_SCOPE0("iree_allocator_system_allocate");
if (!out_ptr) {
return IREE_STATUS_INVALID_ARGUMENT;
} else if (byte_length <= 0) {
return IREE_STATUS_INVALID_ARGUMENT;
}
void* existing_ptr = *out_ptr;
void* ptr = nullptr;
if (existing_ptr && (mode & IREE_ALLOCATION_MODE_TRY_REUSE_EXISTING)) {
ptr = std::realloc(existing_ptr, byte_length);
if (ptr && (mode & IREE_ALLOCATION_MODE_ZERO_CONTENTS)) {
std::memset(ptr, 0, byte_length);
}
} else {
existing_ptr = NULL;
if (mode & IREE_ALLOCATION_MODE_ZERO_CONTENTS) {
ptr = std::calloc(1, byte_length);
} else {
ptr = std::malloc(byte_length);
}
}
if (!ptr) {
return IREE_STATUS_RESOURCE_EXHAUSTED;
}
if (existing_ptr) {
IREE_TRACE_FREE(existing_ptr);
}
IREE_TRACE_ALLOC(ptr, byte_length);
*out_ptr = ptr;
return IREE_STATUS_OK;
}
IREE_API_EXPORT void IREE_API_CALL iree_allocator_system_free(void* self,
void* ptr) {
IREE_TRACE_SCOPE0("iree_allocator_system_free");
IREE_TRACE_FREE(ptr);
if (ptr) {
std::free(ptr);
}
}
//===----------------------------------------------------------------------===//
// iree_string_view_t
//===----------------------------------------------------------------------===//
IREE_API_EXPORT iree_string_view_t IREE_API_CALL
iree_make_cstring_view(const char* str) {
iree_string_view_t result;
result.data = str;
result.size = strlen(str);
return result;
}
IREE_API_EXPORT int IREE_API_CALL
iree_string_view_compare(iree_string_view_t lhs, iree_string_view_t rhs) {
size_t min_size = std::min(lhs.size, rhs.size);
int cmp = strncmp(lhs.data, rhs.data, min_size);
if (cmp != 0) return cmp;
return rhs.size - lhs.size;
}
IREE_API_EXPORT bool IREE_API_CALL iree_string_view_starts_with(
iree_string_view_t value, iree_string_view_t prefix) {
if (!value.data || !prefix.data) {
return false;
} else if (prefix.size > value.size) {
return false;
}
return strncmp(value.data, prefix.data, prefix.size) == 0;
}
IREE_API_EXPORT int IREE_API_CALL iree_string_view_split(
iree_string_view_t value, char split_char, iree_string_view_t* out_lhs,
iree_string_view_t* out_rhs) {
if (!value.data || !value.size) {
return -1;
}
const void* first_ptr = std::memchr(value.data, split_char, value.size);
if (!first_ptr) {
return -1;
}
int offset =
static_cast<int>(reinterpret_cast<const char*>(first_ptr) - value.data);
if (out_lhs) {
out_lhs->data = value.data;
out_lhs->size = offset;
}
if (out_rhs) {
out_rhs->data = value.data + offset + 1;
out_rhs->size = value.size - offset - 1;
}
return offset;
}
static bool MatchPattern(absl::string_view value, absl::string_view pattern) {
size_t next_char_index = pattern.find_first_of("*?");
if (next_char_index == std::string::npos) {
return value == pattern;
} else if (next_char_index > 0) {
if (value.substr(0, next_char_index) !=
pattern.substr(0, next_char_index)) {
return false;
}
value = value.substr(next_char_index);
pattern = pattern.substr(next_char_index);
}
if (value.empty() && pattern.empty()) {
return true;
}
char pattern_char = pattern[0];
if (pattern_char == '*' && pattern.size() > 1 && value.empty()) {
return false;
} else if (pattern_char == '*' && pattern.size() == 1) {
return true;
} else if (pattern_char == '?' || value[0] == pattern_char) {
return MatchPattern(value.substr(1), pattern.substr(1));
} else if (pattern_char == '*') {
return MatchPattern(value, pattern.substr(1)) ||
MatchPattern(value.substr(1), pattern);
}
return false;
}
IREE_API_EXPORT bool IREE_API_CALL iree_string_view_match_pattern(
iree_string_view_t value, iree_string_view_t pattern) {
return MatchPattern(absl::string_view(value.data, value.size),
absl::string_view(pattern.data, pattern.size));
}
//===----------------------------------------------------------------------===//
// iree::FileMapping
//===----------------------------------------------------------------------===//
IREE_API_EXPORT iree_status_t IREE_API_CALL
iree_file_mapping_open_read(iree_string_view_t path, iree_allocator_t allocator,
iree_file_mapping_t** out_file_mapping) {
IREE_TRACE_SCOPE0("iree_file_mapping_open_read");
if (!out_file_mapping) {
return IREE_STATUS_INVALID_ARGUMENT;
}
*out_file_mapping = nullptr;
IREE_API_ASSIGN_OR_RETURN(
auto file_mapping,
FileMapping::OpenRead(std::string(path.data, path.size)));
*out_file_mapping =
reinterpret_cast<iree_file_mapping_t*>(file_mapping.release());
return IREE_STATUS_OK;
}
IREE_API_EXPORT iree_status_t IREE_API_CALL
iree_file_mapping_retain(iree_file_mapping_t* file_mapping) {
IREE_TRACE_SCOPE0("iree_file_mapping_retain");
auto* handle = reinterpret_cast<FileMapping*>(file_mapping);
if (!handle) {
return IREE_STATUS_INVALID_ARGUMENT;
}
handle->AddReference();
return IREE_STATUS_OK;
}
IREE_API_EXPORT iree_status_t IREE_API_CALL
iree_file_mapping_release(iree_file_mapping_t* file_mapping) {
IREE_TRACE_SCOPE0("iree_file_mapping_release");
auto* handle = reinterpret_cast<FileMapping*>(file_mapping);
if (!handle) {
return IREE_STATUS_INVALID_ARGUMENT;
}
handle->ReleaseReference();
return IREE_STATUS_OK;
}
IREE_API_EXPORT iree_byte_span_t IREE_API_CALL
iree_file_mapping_data(iree_file_mapping_t* file_mapping) {
IREE_TRACE_SCOPE0("iree_file_mapping_data");
auto* handle = reinterpret_cast<FileMapping*>(file_mapping);
CHECK(handle) << "NULL file_mapping handle";
auto data = handle->data();
return {const_cast<uint8_t*>(data.data()), data.size()};
}
} // namespace iree