blob: 3f49b72c23029839c4688d8e1fd132d51aec0866 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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
*
* http://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.
*/
/**
* @file
* @ingroup Port
* @brief Static shared library
*/
#include <string.h>
#include <stdlib.h>
#include "hyport.h"
#if defined(HYVM_STATIC_LINKAGE)
#include "hystatic.h"
extern HyPrimitiveTable HyLinkedNatives;
void *
upLookupName (char *name, HyPrimitiveTableSlot * table)
{
void *result;
while (!((table->name == (char *) 0) && (table->funcOrTable == (void *) 0)))
{
if (table->name == (char *) 0)
{
result =
upLookupName (name,
(HyPrimitiveTableSlot *) (table->funcOrTable));
if (result != (void *) 0 /*HyDefaultFailPrimitive */ )
return result;
}
else
{
if (strcmp (name, table->name) == 0)
return table->funcOrTable;
}
table++;
}
return (void *) 0 /*HyDefaultFailPrimitive */ ;
}
/**
* Close a static library.
*
* @param[in] portLibrary The port library.
* @param[in] descriptor Static library handle to close.
*
* @return 0 on success, any other value on failure.
*/
UDATA VMCALL
hysl_up_close_shared_library (struct HyPortLibrary *portLibrary,
UDATA descriptor)
{
return 0;
}
/**
* Opens a static library .
*
* @param[in] portLibrary The port library.
* @param[in] name path Null-terminated string containing the static library.
* @param[out] descriptor Pointer to memory which is filled in with static-library handle on success.
* @param[in] decorate Boolean value indicates whether name should be decorated if it contains path information and cannot be found.
*
* @return 0 on success, any other value on failure.
*
* @note contents of descriptor are undefined on failure.
*/
UDATA VMCALL
hysl_up_open_shared_library (struct HyPortLibrary * portLibrary, char *name,
UDATA * descriptor, BOOLEAN decorate)
{
void *result;
if (result = upLookupName (name, &HyLinkedNatives[0]))
{
*descriptor = (UDATA) result;
return 0;
}
else
{
return portLibrary->error_set_last_error_with_message (portLibrary,
HYPORT_SL_NOT_FOUND,
"Not statically linked");
}
}
/**
* Search for a function named 'name' taking argCount in the static library 'descriptor'.
*
* @param[in] portLibrary The port library.
* @param[in] descriptor Static library to search.
* @param[in] name Function to look up.
* @param[out] func Pointer to the function.
* @param[in] argSignature Argument signature.
*
* @return 0 on success, any other value on failure.
*
* @note contents of func are undefined on failure.
*/
UDATA VMCALL
hysl_up_lookup_name (struct HyPortLibrary * portLibrary, UDATA descriptor,
char *name, UDATA * func, const char *argSignature)
{
void *result;
if (result = upLookupName (name, (HyPrimitiveTableSlot *) descriptor))
{
*func = (UDATA) result;
return 0;
}
else
{
return 1;
}
}
typedef struct
{
UDATA descriptor;
UDATA tag;
} hysplit_sl_handle;
#define HYFLAG_SL_LINKED 0
#define HYFLAG_SL_LOADED 1
/* support BOTH types of libraries */
/**
* Opens a static/shared library .
*
* @param[in] portLibrary The port library.
* @param[in] name path Null-terminated string containing the library.
* @param[out] descriptor Pointer to memory which is filled in with library handle on success.
* @param[in] decorate Boolean value indicates whether name should be decorated if it contains path information and cannot be found.
*
* @return 0 on success, any other value on failure.
*
* @note contents of descriptor are undefined on failure.
*/
UDATA VMCALL
hysl_split_open_shared_library (struct HyPortLibrary *portLibrary, char *name,
UDATA * descriptor, BOOLEAN decorate)
{
UDATA result;
UDATA tag;
tag = HYFLAG_SL_LINKED;
result =
hysl_up_open_shared_library (portLibrary, name, descriptor, decorate);
if (result == HYPORT_SL_NOT_FOUND)
{
result =
hysl_open_shared_library (portLibrary, name, descriptor, decorate);
tag = HYFLAG_SL_LOADED;
}
if (result == 0)
{
hysplit_sl_handle *handle;
handle =
portLibrary->mem_allocate_memory (portLibrary,
sizeof (hysplit_sl_handle));
if (handle == NULL)
{
if (tag == HYFLAG_SL_LOADED)
{
hysl_close_shared_library (portLibrary, *descriptor);
}
return portLibrary->error_set_last_error_with_message (portLibrary,
HYPORT_SL_INVALID,
"Out of memory");
}
handle->descriptor = *descriptor;
handle->tag = tag;
*descriptor = (UDATA) handle;
}
return result;
}
/**
* Close a static or shared library.
*
* @param[in] portLibrary The port library.
* @param[in] descriptor Library handle to close.
*
* @return 0 on success, any other value on failure.
*/
UDATA VMCALL
hysl_split_close_shared_library (struct HyPortLibrary * portLibrary,
UDATA descriptor)
{
hysplit_sl_handle *handle = (hysplit_sl_handle *) descriptor;
UDATA result;
if (handle->tag == HYFLAG_SL_LOADED)
{
result = hysl_close_shared_library (portLibrary, handle->descriptor);
}
else
{
result = hysl_up_close_shared_library (portLibrary, handle->descriptor);
}
portLibrary->mem_free_memory (portLibrary, handle);
return result;
}
/**
* Search for a function named 'name' taking argCount in the static/shared library 'descriptor'.
*
* @param[in] portLibrary The port library.
* @param[in] descriptor Library to search.
* @param[in] name Function to look up.
* @param[out] func Pointer to the function.
* @param[in] argSignature Argument signature.
*
* @return 0 on success, any other value on failure.
*
* @note contents of func are undefined on failure.
*/
UDATA VMCALL
hysl_split_lookup_name (struct HyPortLibrary * portLibrary, UDATA descriptor,
char *name, UDATA * func, const char *argSignature)
{
hysplit_sl_handle *handle = (hysplit_sl_handle *) descriptor;
if (handle->tag == HYFLAG_SL_LOADED)
{
return hysl_lookup_name (portLibrary, handle->descriptor, name, func,
argSignature);
}
else
{
return hysl_up_lookup_name (portLibrary, handle->descriptor, name, func,
argSignature);
}
}
#endif