Skip to content

Commit

Permalink
loader: Add documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
chfast committed Jul 5, 2018
1 parent 44f5e75 commit 575eb79
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
31 changes: 31 additions & 0 deletions include/evmc/loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
extern "C" {
#endif

/** Error codes for the EVMC loader. */
enum evmc_loader_error_code
{
EVMC_ERRC_SUCCESS = 0,
Expand All @@ -17,6 +18,36 @@ enum evmc_loader_error_code
EVMC_ERRC_INVALID_ARGUMENT,
};

/**
* Dynamically loads the shared object and creates a EVM instance.
*
* This function tries to open a DLL at the given `filename`. On UNIX-like systems dlopen() function
* is used. On Windows LoadLibrary() function is used.
*
* If the file does not exists or is not a valid shared library the ::EVMC_ERRC_CANNOT_OPEN error
* code is signaled and NULL is returned.
*
* After the DLL is successfully loaded the function tries to find the EVM create function in the
* library. The `filename` is used to guess the EVM name and the name of the create function.
* The create function name is constructed as following:
* - the filename is taken from the path,
* - the "lib" prefix and file extension are stripped from the name,
* - all "-" are replaced with "_" to construct _full name_,
* - the last stem from the _full name_ separated with "_" is taken to construct the _short name_,
* - the name "evmc_create_" + _full name_ is checked in the library,
* - the name "evmc_create_" + _short name_ is checked in the library.
*
* If the create function is found in the library, the EVM instance is create and returned.
* Otherwise, the ::EVMC_ERRC_SYMBOL_NOT_FOUND error code is signaled and NULL is returned.
*
* @param filename The null terminated path (absolute or relative) to the shared library
* containing the EVM implementation. If the value is NULL, an empty C-string
* or longer than the path maximum length the ::EVMC_ERRC_INVALID_ARGUMENT is
* signaled.
* @param error_code The pointer to the error code. If not NULL the value is set to
* ::EVMC_ERRC_SUCCESS on success or any other error code as described above.
* @return The pointer to EVM instance if loaded successfully or NULL.
*/
struct evmc_instance* evmc_load(const char* filename, enum evmc_loader_error_code* error_code);

#if __cplusplus
Expand Down
7 changes: 7 additions & 0 deletions lib/loader/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,32 +66,39 @@ struct evmc_instance* evmc_load(const char* filename, enum evmc_loader_error_cod
goto exit;
}

// Create name buffer with the prefix.
const char prefix[] = "evmc_create_";
const size_t prefix_length = strlen(prefix);
char name[sizeof(prefix) + PATH_MAX_LENGHT];
strcpy_s(name, sizeof(name), prefix);

// Find filename in the path.
const char* sep_pos = strrchr(filename, '/');
const char* name_pos = sep_pos ? sep_pos + 1 : filename;

// Skip "lib" prefix if present.
const char lib_prefix[] = "lib";
const size_t lib_prefix_length = strlen(lib_prefix);
if (strncmp(name_pos, lib_prefix, lib_prefix_length) == 0)
name_pos += lib_prefix_length;

strcpy_s(name + prefix_length, PATH_MAX_LENGHT, name_pos);

// Trim the file extension.
char* ext_pos = strrchr(name, '.');
if (ext_pos)
*ext_pos = 0;

// Replace all "-" with "_".
char* dash_pos = name;
while ((dash_pos = strchr(dash_pos, '-')) != NULL)
*dash_pos++ = '_';

// Search for the "full name" based function name.
evmc_create_fn create_fn = DLL_GET_CREATE_FN(handle, name);
if (!create_fn)
{
// Try the "short name" based function name.
const char* short_name_pos = strrchr(name, '_');
if (short_name_pos)
{
Expand Down

0 comments on commit 575eb79

Please sign in to comment.