Skip to content

Commit 93a6432

Browse files
committed
[[ LCB ]] Improve builtin module emission and loading
This patch reworks the way builtin modules are handled. When lc-compile is run in --outputc mode, it will now emit a C byte array for each module which is passed on the command line along with a unique global class instance which calls MCScriptRegisterBuiltinModule in its constructor. This function takes a fixed format static record which contains the module data and its (C) initializer and finalizer. When called, the function will link the static record into a singly-linked list of builtin modules. When MCScriptInitialize is called, it will now iterate through this list loading each module, and setting each one's initializer and finalizer. It will then ensure each builtin module is usable. The initializer and finalizer are now called by libscript itself - the initializer when the module is made usable, and the finalizer when the module is (finally) destroyed. This new mechanism means that builtin modules do not all have to be compiled together into one C file, but compiled and linked into the engine separately. Note: It is necessary to 'force_load' (Mac/iOS), 'WHOLEARCHIVE' (Win) and 'whole-archive/no-whole-archive' (Linux) any libs containing builtin modules when linking the final executable, otherwise the global objects used for registration will be stripped. Note: We need to use 'all_dependent_settings' on Mac, iOS and Win to broadcast the linker setting to the top-level target. This is in contrast to 'direct_dependent_settings' on Linux and Android to stop multiple repeats of the same linker option.
1 parent f83d351 commit 93a6432

File tree

17 files changed

+178
-197
lines changed

17 files changed

+178
-197
lines changed

engine/lcb-modules.gyp

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,61 @@
2929
],
3030
},
3131
},
32-
32+
33+
'conditions':
34+
[
35+
[
36+
'OS == "win"',
37+
{
38+
'all_dependent_settings':
39+
{
40+
'msvs_settings':
41+
{
42+
'VCLinkerTool':
43+
{
44+
'AdditionalOptions':
45+
[
46+
'/WHOLEARCHIVE:<(PRODUCT_DIR)/lib/engine_lcb_modules.lib',
47+
],
48+
},
49+
},
50+
},
51+
},
52+
],
53+
[
54+
'OS == "mac" or OS == "ios"',
55+
{
56+
'all_dependent_settings':
57+
{
58+
'xcode_settings':
59+
{
60+
'OTHER_LDFLAGS':
61+
[
62+
'-force_load <(PRODUCT_DIR)/libengine_lcb_modules.a',
63+
],
64+
},
65+
},
66+
},
67+
],
68+
[
69+
'OS == "android" or OS == "linux"',
70+
{
71+
'direct_dependent_settings':
72+
{
73+
'link_settings':
74+
{
75+
'ldflags':
76+
[
77+
'-Wl,--whole-archive',
78+
'-Wl,<(PRODUCT_DIR)/obj.target/engine/libengine_lcb_modules.a',
79+
'-Wl,--no-whole-archive',
80+
],
81+
},
82+
},
83+
},
84+
],
85+
],
86+
3387
'actions':
3488
[
3589
{
@@ -47,7 +101,7 @@
47101

48102
'outputs':
49103
[
50-
'<(INTERMEDIATE_DIR)/engine_lcb_modules.c',
104+
'<(INTERMEDIATE_DIR)/engine_lcb_modules.cpp',
51105

52106
# A specific output file is required here to ensure that
53107
# all build systems create the output directory while
@@ -62,7 +116,7 @@
62116
'--bootstrap',
63117
'--inputg', '../toolchain/lc-compile/src/grammar.g',
64118
'--outputi', '<(PRODUCT_DIR)/modules/lci',
65-
'--outputc', '<(INTERMEDIATE_DIR)/engine_lcb_modules.c',
119+
'--outputc', '<(INTERMEDIATE_DIR)/engine_lcb_modules.cpp',
66120
'<@(_inputs)',
67121
],
68122
},

engine/src/dsklnxmain.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@ void X_main_loop(void)
5050
X_main_loop_iteration();
5151
}
5252

53-
extern "C" bool MCModulesInitialize();
54-
extern "C" void MCModulesFinalize();
55-
5653
int platform_main(int argc, char *argv[], char *envp[])
5754
{
5855
// On Linux, the argv and envp could be in pretty much any format. The
@@ -73,12 +70,6 @@ int platform_main(int argc, char *argv[], char *envp[])
7370
exit(-1);
7471
}
7572

76-
if (!MCModulesInitialize())
77-
{
78-
fprintf(stderr, "Fatal: built-in module initialization failed\n");
79-
exit(-1);
80-
}
81-
8273
if (!MCScriptInitialize())
8374
{
8475
fprintf(stderr, "Fatal: script initialization failed\n");
@@ -148,7 +139,6 @@ int platform_main(int argc, char *argv[], char *envp[])
148139
int t_exit_code = X_close();
149140

150141
MCScriptFinalize();
151-
MCModulesFinalize();
152142
MCFinalize();
153143

154144
exit(t_exit_code);

engine/src/dskw32main.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,6 @@ static void CALLBACK LoopFiberRoutine(void *p_parameter)
130130

131131
////////////////////////////////////////////////////////////////////////////////
132132

133-
extern "C" bool MCModulesInitialize();
134-
extern "C" void MCModulesFinalize();
135-
136133
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
137134
{
138135
// MW-2010-05-09: Elevated process handling - if the cmd line begins with '-elevated-slave'
@@ -218,8 +215,9 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
218215
++csptr;
219216
}
220217

221-
if (!MCInitialize() || !MCSInitialize() ||
222-
!MCModulesInitialize() || !MCScriptInitialize())
218+
if (!MCInitialize() ||
219+
!MCSInitialize() ||
220+
!MCScriptInitialize())
223221
exit(-1);
224222

225223
// Ensure the command line variable gets set
@@ -329,7 +327,6 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
329327
MCValueRelease(MCcmdline);
330328

331329
MCScriptFinalize();
332-
MCModulesFinalize();
333330
MCFinalize();
334331

335332
if (t_tsf_mgr != nil)

engine/src/em-main.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
3232

3333
#include <unistd.h>
3434

35-
/* Declarations that should probably be in a header */
36-
extern "C" bool MCModulesInitialize(void);
37-
3835
/* ================================================================
3936
* Emscripten engine start-up
4037
* ================================================================ */
@@ -64,10 +61,6 @@ platform_main(int argc, char *argv[], char *envp[])
6461
{
6562
MCEmscriptenBootError("LCB VM initialisation");
6663
}
67-
if (!MCModulesInitialize())
68-
{
69-
MCEmscriptenBootError("LCB library initialisation");
70-
}
7164

7265
/* ---------- Process command-line arguments.
7366
* Emscripten usually passes fairly meaningless values here. */

engine/src/mac-core.mm

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2001,9 +2001,6 @@ static void display_reconfiguration_callback(CGDirectDisplayID display, CGDispla
20012001

20022002
////////////////////////////////////////////////////////////////////////////////
20032003

2004-
extern "C" bool MCModulesInitialize(void);
2005-
extern "C" void MCModulesFinalize(void);
2006-
20072004
int platform_main(int argc, char *argv[], char *envp[])
20082005
{
20092006
extern bool MCS_mac_elevation_bootstrap_main(int argc, char* argv[]);
@@ -2023,8 +2020,9 @@ int platform_main(int argc, char *argv[], char *envp[])
20232020
// Register for reconfigurations.
20242021
CGDisplayRegisterReconfigurationCallback(display_reconfiguration_callback, nil);
20252022

2026-
if (!MCInitialize() || !MCSInitialize() ||
2027-
!MCModulesInitialize() || !MCScriptInitialize())
2023+
if (!MCInitialize() ||
2024+
!MCSInitialize() ||
2025+
!MCScriptInitialize())
20282026
exit(-1);
20292027

20302028
// On OSX, argv and envp are encoded as UTF8
@@ -2076,7 +2074,6 @@ int platform_main(int argc, char *argv[], char *envp[])
20762074
[t_pool release];
20772075

20782076
MCScriptFinalize();
2079-
MCModulesFinalize();
20802077
MCFinalize();
20812078

20822079
return 0;

engine/src/mblandroiddc.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,6 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
5656

5757
#include "libscript/script.h"
5858

59-
extern "C" bool MCModulesInitialize();
60-
6159
////////////////////////////////////////////////////////////////////////////////
6260

6361
// Various globals depended on by other parts of the engine.
@@ -1971,7 +1969,6 @@ JNIEXPORT void JNICALL Java_com_runrev_android_Engine_doCreate(JNIEnv *env, jobj
19711969
{
19721970
MCInitialize();
19731971
MCSInitialize();
1974-
MCModulesInitialize();
19751972
MCScriptInitialize();
19761973

19771974
MCLog("doCreate called");

engine/src/mbliphoneapp.mm

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,8 +2053,6 @@ Exec_stat MCIPhoneHandleMessage(MCNameRef p_message, MCParameter *p_parameters)
20532053
return s;
20542054
}
20552055

2056-
extern "C" bool MCModulesInitialize();
2057-
20582056
MC_DLLEXPORT_DEF int platform_main(int argc, char *argv[], char *envp[])
20592057
{
20602058
#if defined(_DEBUG) && defined(_VALGRIND)
@@ -2065,8 +2063,9 @@ MC_DLLEXPORT_DEF int platform_main(int argc, char *argv[], char *envp[])
20652063
}
20662064
#endif
20672065

2068-
if (!MCInitialize() || !MCSInitialize() ||
2069-
!MCModulesInitialize() || !MCScriptInitialize())
2066+
if (!MCInitialize() ||
2067+
!MCSInitialize() ||
2068+
!MCScriptInitialize())
20702069
return -1;
20712070

20722071
int t_exit_code;

engine/src/srvmain.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -612,13 +612,11 @@ void X_main_loop(void)
612612

613613
////////////////////////////////////////////////////////////////////////////////
614614

615-
extern "C" bool MCModulesInitialize();
616-
extern "C" void MCModulesFinalize();
617-
618615
int platform_main(int argc, char *argv[], char *envp[])
619616
{
620-
if (!MCInitialize() || !MCSInitialize() ||
621-
!MCModulesInitialize() || !MCScriptInitialize())
617+
if (!MCInitialize() ||
618+
!MCSInitialize() ||
619+
!MCScriptInitialize())
622620
exit(-1);
623621

624622
// THIS IS MAC SPECIFIC AT THE MOMENT BUT SHOULD WORK ON LINUX
@@ -672,7 +670,6 @@ int platform_main(int argc, char *argv[], char *envp[])
672670
MCMemoryDeleteArray(t_new_envp);
673671

674672
MCScriptFinalize();
675-
MCModulesFinalize();
676673
MCFinalize();
677674

678675
exit(t_exit_code);

libfoundation/src/system-commandline.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,9 @@ __MCSCommandLineFinalize (void)
237237
* Windows-specific functions
238238
* ================================================================ */
239239

240+
/* This is needed for CommandLineToArgvW */
241+
#pragma comment(lib, "shell32.lib")
242+
240243
MC_DLLEXPORT_DEF bool
241244
MCSCommandLineCaptureWindows (void)
242245
{

libscript/include/libscript/script.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ bool MCScriptCreateModuleFromStream(MCStreamRef stream, MCScriptModuleRef& r_mod
165165
// Load a module from a blob
166166
MC_DLLEXPORT bool MCScriptCreateModuleFromData(MCDataRef data, MCScriptModuleRef & r_module);
167167

168+
// Set initializer / finalizer
169+
void MCScriptSetModuleLifecycleFunctions(MCScriptModuleRef module, bool (*initializer)(void), void (*finalizer)(void));
170+
168171
// Lookup the module with the given name. Returns false if no such module exists.
169172
bool MCScriptLookupModule(MCNameRef name, MCScriptModuleRef& r_module);
170173

0 commit comments

Comments
 (0)