Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit ad659e0

Browse files
committed
[[ SysLibrary ]] Update libscript to use system library functions
This patch updates libscript to use the new system library loading functions, removing the per-platform code which was previously present. Libraries are now all loaded via a callback function, which degrades gracefully to using MCSLibraryCreateWithPath if none is set. This means that lc-run can continue to function as it does now; whereas all library loading in the engine is done using MCU_library_load.
1 parent a0c67f2 commit ad659e0

File tree

6 files changed

+115
-187
lines changed

6 files changed

+115
-187
lines changed

engine/src/exec-extension.cpp

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -243,27 +243,59 @@ void MCEngineLoadExtensionFromData(MCExecContext& ctxt, MCDataRef p_extension_da
243243
// linux-x86_64/<name>.so
244244
// win-x86/<name>.dll
245245
//
246-
static bool MCEngineResolveSharedLibrary(MCScriptModuleRef p_module, MCStringRef p_name, MCStringRef& r_path)
246+
static bool MCEngineLoadLibrary(MCScriptModuleRef p_module, MCStringRef p_name, MCSLibraryRef& r_library)
247247
{
248248
// If the module has no resource path, then it has no code.
249249
MCAutoStringRef t_resource_path;
250250
if (!MCEngineLookupResourcePathForModule(p_module, Out(t_resource_path)))
251251
return false;
252252

253-
if (MCStringIsEmpty(*t_resource_path))
254-
return false;
255-
256-
#if defined(_MACOSX)
257-
return MCStringFormat(r_path, "%@/code/mac/%@.dylib", *t_resource_path, p_name);
258-
#elif defined(_LINUX) && defined(__32_BIT__)
259-
return MCStringFormat(r_path, "%@/code/linux-x86/%@.so", *t_resource_path, p_name);
260-
#elif defined(_LINUX) && defined(__64_BIT__)
261-
return MCStringFormat(r_path, "%@/code/linux-x86_64/%@.so", *t_resource_path, p_name);
262-
#elif defined(_WINDOWS)
263-
return MCStringFormat(r_path, "%@/code/win-x86/%@.dll", *t_resource_path, p_name);
253+
MCSLibraryRef t_library = nullptr;
254+
if (t_resource_path.IsSet() &&
255+
!MCStringIsEmpty(*t_resource_path))
256+
{
257+
#if defined(__MAC__)
258+
static const char *kLibraryFormat = "%@/code/mac/%@";
259+
#elif defined(__LINUX__) && defined(__32_BIT__)
260+
static const char *kLibraryFormat = "%@/code/linux-x86/%@";
261+
#elif defined(__LINUX__) && defined(__64_BIT__)
262+
static const char *kLibraryFormat = "%@/code/linux-x86_64/%@";
263+
#elif defined(__WINDOWS__)
264+
static const char *kLibraryFormat = "%@/code/win-x86/%@";
265+
#elif defined(__ANDROID__)
266+
static const char *kLibraryFormat = "%@/code/android-armv6/%@";
267+
#elif defined(__IOS__)
268+
static const char *kLibraryFormat = "%@/code/ios/%@";
269+
#elif defined(__EMSCRIPTEN__)
270+
static const char *kLibraryFormat = "%@/code/emscripten/%@";
264271
#else
265-
return false;
272+
#error No default code path set for this platform
266273
#endif
274+
MCAutoStringRef t_ext_path;
275+
if (!MCStringFormat(&t_ext_path,
276+
kLibraryFormat,
277+
*t_resource_path,
278+
p_name))
279+
{
280+
return false;
281+
}
282+
283+
t_library = MCU_library_load(*t_ext_path);
284+
}
285+
286+
if (t_library == nullptr)
287+
{
288+
t_library = MCU_library_load(p_name);
289+
}
290+
291+
if (t_library == nullptr)
292+
{
293+
return false;
294+
}
295+
296+
r_library = t_library;
297+
298+
return true;
267299
}
268300

269301
void MCEngineExecLoadExtension(MCExecContext& ctxt, MCStringRef p_filename, MCStringRef p_resource_path)
@@ -280,7 +312,7 @@ void MCEngineExecLoadExtension(MCExecContext& ctxt, MCStringRef p_filename, MCSt
280312

281313
// Make sure we set the shared library callback - this should be done in
282314
// module init for 'extension' when we have such a mechanism.
283-
MCScriptSetResolveSharedLibraryCallback(MCEngineResolveSharedLibrary);
315+
MCScriptSetLoadLibraryCallback(MCEngineLoadLibrary);
284316

285317
MCEngineLoadExtensionFromData(ctxt, *t_data, p_resource_path);
286318
}

libscript/include/libscript/script.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@
2020
////////////////////////////////////////////////////////////////////////////////
2121

2222
#ifndef __MC_FOUNDATION__
23-
#include "foundation.h"
23+
#include <foundation.h>
24+
#endif
25+
26+
#ifndef __MC_FOUNDATION_SYSTEM__
27+
#include <foundation-system.h>
2428
#endif
2529

2630
////////////////////////////////////////////////////////////////////////////////
@@ -35,14 +39,12 @@ typedef MCScriptInstance *MCScriptInstanceRef;
3539

3640
////////////////////////////////////////////////////////////////////////////////
3741

38-
typedef bool (*MCScriptResolveSharedLibraryCallback)(MCScriptModuleRef module, MCStringRef name, MCStringRef& r_path);
42+
typedef bool (*MCScriptLoadLibraryCallback)(MCScriptModuleRef module, MCStringRef name, MCSLibraryRef& r_library);
3943

4044
bool MCScriptInitialize(void);
4145
void MCScriptFinalize(void);
4246

43-
void MCScriptSetResolveSharedLibraryCallback(MCScriptResolveSharedLibraryCallback callback);
44-
45-
bool MCScriptResolveSharedLibrary(MCScriptModuleRef module, MCStringRef name, MCStringRef& r_path);
47+
void MCScriptSetLoadLibraryCallback(MCScriptLoadLibraryCallback callback);
4648

4749
////////////////////////////////////////////////////////////////////////////////
4850

libscript/src/script-instance.cpp

Lines changed: 14 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,14 @@
1414
You should have received a copy of the GNU General Public License
1515
along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
1616

17-
#include "libscript/script.h"
18-
#include "script-private.h"
17+
#include <foundation.h>
18+
#include <foundation-auto.h>
19+
#include <foundation-system.h>
1920

2021
#include "ffi.h"
2122

22-
#include "foundation-auto.h"
23-
24-
#ifdef _WIN32
25-
#include <windows.h>
26-
#else
27-
#include <dlfcn.h>
28-
#endif
29-
23+
#include "libscript/script.h"
24+
#include "script-private.h"
3025
#include "script-bytecode.hpp"
3126

3227
////////////////////////////////////////////////////////////////////////////////
@@ -581,136 +576,6 @@ __MCScriptSplitForeignBindingString(MCStringRef& x_string,
581576
return true;
582577
}
583578

584-
static bool
585-
__MCScriptPlatformLoadSharedLibrary(MCStringRef p_path,
586-
void*& r_handle)
587-
{
588-
#if defined(_WIN32)
589-
HMODULE t_module;
590-
MCAutoStringRefAsWString t_library_wstr;
591-
if (!t_library_wstr.Lock(p_path))
592-
{
593-
return false;
594-
}
595-
596-
t_module = LoadLibraryW(*t_library_wstr);
597-
if (t_module == NULL)
598-
{
599-
return false;
600-
}
601-
602-
r_handle = (void *)t_module;
603-
#else
604-
MCAutoStringRefAsUTF8String t_utf8_library;
605-
if (!t_utf8_library.Lock(p_path))
606-
{
607-
return false;
608-
}
609-
610-
void *t_module;
611-
t_module = dlopen(*t_utf8_library, RTLD_LAZY);
612-
if (t_module == NULL)
613-
{
614-
return false;
615-
}
616-
617-
r_handle = (void *)t_module;
618-
#endif
619-
return true;
620-
}
621-
622-
static bool
623-
__MCScriptPlatformLoadSharedLibraryFunction(void *p_module,
624-
MCStringRef p_function,
625-
void*& r_pointer)
626-
{
627-
MCAutoStringRefAsCString t_function_name;
628-
if (!t_function_name.Lock(p_function))
629-
{
630-
return false;
631-
}
632-
633-
void *t_pointer;
634-
#if defined(_WIN32)
635-
t_pointer = GetProcAddress((HMODULE)p_module,
636-
*t_function_name);
637-
#else
638-
t_pointer = dlsym(p_module,
639-
*t_function_name);
640-
#endif
641-
642-
r_pointer = t_pointer;
643-
644-
return true;
645-
}
646-
647-
static bool
648-
__MCScriptLoadSharedLibrary(MCScriptModuleRef p_module,
649-
MCStringRef p_library,
650-
void*& r_handle)
651-
{
652-
// If there is no library name then we resolve to the executable module.
653-
if (MCStringIsEmpty(p_library))
654-
{
655-
#if defined(_WIN32)
656-
r_handle = GetModuleHandle(NULL);
657-
#elif defined(TARGET_SUBPLATFORM_ANDROID)
658-
// IM-2016-03-04: [[ Bug 16917 ]] dlopen can fail if the full path to the library is not
659-
// given, so first resolve the path to the library.
660-
extern bool MCAndroidResolveLibraryPath(MCStringRef p_library,
661-
MCStringRef &r_path);
662-
MCAutoStringRef t_path;
663-
if (!MCAndroidResolveLibraryPath(MCSTR("librevandroid.so"),
664-
&t_path))
665-
{
666-
return false;
667-
}
668-
669-
MCAutoStringRefAsCString t_cstring;
670-
if (!t_cstring.Lock(*t_path))
671-
{
672-
return false;
673-
}
674-
675-
r_handle = dlopen(*t_cstring, 0);
676-
#else
677-
r_handle = dlopen(NULL, 0);
678-
#endif
679-
return true;
680-
}
681-
682-
// If there is no slash in the name, we try to resolve based on the module.
683-
uindex_t t_offset;
684-
if (!MCStringFirstIndexOfChar(p_library,
685-
'/',
686-
0,
687-
kMCStringOptionCompareExact,
688-
t_offset))
689-
{
690-
MCAutoStringRef t_mapped_library;
691-
if (MCScriptResolveSharedLibrary(p_module,
692-
p_library,
693-
Out(t_mapped_library)))
694-
{
695-
if (__MCScriptPlatformLoadSharedLibrary(*t_mapped_library,
696-
r_handle))
697-
{
698-
return true;
699-
}
700-
}
701-
}
702-
703-
// If the previous two things failed, then just try to load the library as written.
704-
if (__MCScriptPlatformLoadSharedLibrary(p_library,
705-
r_handle))
706-
{
707-
return true;
708-
}
709-
710-
// Oh dear - no native code library for us!
711-
return false;
712-
}
713-
714579
static bool
715580
__MCScriptResolveForeignFunctionBinding(MCScriptInstanceRef p_instance,
716581
MCScriptForeignHandlerDefinition *p_handler,
@@ -792,10 +657,11 @@ __MCScriptResolveForeignFunctionBinding(MCScriptInstanceRef p_instance,
792657
return MCScriptThrowClassNotAllowedInCBindingError();
793658
}
794659

795-
void *t_module;
796-
if (!__MCScriptLoadSharedLibrary(MCScriptGetModuleOfInstance(p_instance),
797-
*t_library,
798-
t_module))
660+
/* TODO: This leaks a module handle! */
661+
MCSLibraryRef t_module;
662+
if (!MCScriptLoadLibrary(MCScriptGetModuleOfInstance(p_instance),
663+
*t_library,
664+
t_module))
799665
{
800666
if (r_bound == nil)
801667
{
@@ -807,10 +673,10 @@ __MCScriptResolveForeignFunctionBinding(MCScriptInstanceRef p_instance,
807673
return true;
808674
}
809675

810-
void *t_pointer;
811-
if (!__MCScriptPlatformLoadSharedLibraryFunction(t_module,
812-
*t_function,
813-
t_pointer))
676+
void *t_pointer =
677+
MCSLibraryLookupSymbol(t_module,
678+
*t_function);
679+
if (t_pointer == nullptr)
814680
{
815681
return false;
816682
}

libscript/src/script-module.cpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616

1717
#include <foundation.h>
1818
#include <foundation-auto.h>
19+
#include <foundation-system.h>
1920

2021
#include <libscript/script.h>
2122
#include <libscript/script-auto.h>
2223

2324
#include "script-private.h"
24-
2525
#include "script-bytecode.hpp"
2626

2727
#include <stddef.h>
@@ -711,17 +711,11 @@ bool MCScriptEnsureModuleIsUsable(MCScriptModuleRef self)
711711
MCScriptForeignType *t_type;
712712
t_type = static_cast<MCScriptForeignType *>(self -> types[i]);
713713

714-
void *t_symbol;
715-
#ifdef _WIN32
716-
t_symbol = GetProcAddress(GetModuleHandle(NULL), MCStringGetCString(t_type -> binding));
717-
#elif defined(__EMSCRIPTEN__)
718-
void *t_handle = dlopen(NULL, RTLD_LAZY);
719-
t_symbol = dlsym(t_handle, MCStringGetCString(t_type->binding));
720-
dlclose(t_handle);
721-
#else
722-
t_symbol = dlsym(RTLD_DEFAULT, MCStringGetCString(t_type -> binding));
723-
#endif
724-
if (t_symbol == nil)
714+
void *t_symbol = nullptr;
715+
t_symbol = MCSLibraryLookupSymbol(MCScriptGetLibrary(),
716+
t_type->binding);
717+
718+
if (t_symbol == nullptr)
725719
{
726720
MCErrorThrowGenericWithMessage(MCSTR("%{name} not usable - unable to resolve foreign type '%{type}'"),
727721
"name", self -> name,

0 commit comments

Comments
 (0)