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

Commit f77c052

Browse files
committed
[[ Bug 19064 ]] Load builtin extension modules at engine startup
This patch loads any builtin modules which are library or widget extensions on startup of the script engine. At present they are loaded in X_open, before the mainstack is processed and unloaded in X_close, before anything else.
1 parent 0e94d27 commit f77c052

File tree

5 files changed

+87
-8
lines changed

5 files changed

+87
-8
lines changed

engine/src/exec-extension.cpp

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -317,10 +317,27 @@ void MCEngineExecLoadExtension(MCExecContext& ctxt, MCStringRef p_filename, MCSt
317317
MCEngineLoadExtensionFromData(ctxt, *t_data, p_resource_path);
318318
}
319319

320+
/* This function frees the given loaded extension. It must have already been
321+
* removed from the global MCextensions lists. */
322+
static void
323+
__MCEngineFreeExtension(MCLoadedExtension *p_extension)
324+
{
325+
if (p_extension -> instance != nil)
326+
MCScriptReleaseInstance(p_extension -> instance);
327+
MCScriptReleaseModule(p_extension -> module);
328+
MCValueRelease(p_extension -> module_name);
329+
MCValueRelease(p_extension -> resource_path);
330+
MCMemoryDelete(p_extension);
331+
}
332+
320333
void MCEngineExecUnloadExtension(MCExecContext& ctxt, MCStringRef p_module_name)
321334
{
322335
MCNewAutoNameRef t_name;
323-
MCNameCreate(p_module_name, &t_name);
336+
if (!MCNameCreate(p_module_name, &t_name))
337+
{
338+
ctxt.Throw();
339+
return;
340+
}
324341

325342
for(MCLoadedExtension *t_previous = nil, *t_ext = MCextensions; t_ext != nil; t_previous = t_ext, t_ext = t_ext -> next)
326343
if (MCNameIsEqualTo(t_ext -> module_name, *t_name))
@@ -355,20 +372,19 @@ void MCEngineExecUnloadExtension(MCExecContext& ctxt, MCStringRef p_module_name)
355372
ctxt . SetTheResultToCString("module in use");
356373
return;
357374
}
358-
359-
if (t_ext -> instance != nil)
360-
MCScriptReleaseInstance(t_ext -> instance);
361-
MCScriptReleaseModule(t_ext -> module);
362-
MCValueRelease(t_ext -> module_name);
363-
MCValueRelease(t_ext -> resource_path);
375+
376+
/* Unlink the extension from the global linked-list */
364377
if (t_previous != nil)
365378
t_previous -> next = t_ext -> next;
366379
else
367380
MCextensions = t_ext -> next;
368-
MCMemoryDelete(t_ext);
369381

382+
/* Makes sure the global handler list is refreshed on next use */
370383
MCextensionschanged = true;
371384

385+
/* Free the extension struct and things it owns */
386+
__MCEngineFreeExtension(t_ext);
387+
372388
return;
373389
}
374390

@@ -1435,4 +1451,35 @@ static bool __script_try_to_convert_to_foreign(MCExecContext& ctxt, MCTypeInfoRe
14351451
return true;
14361452
}
14371453

1454+
////////////////////////////////////////////////////////////////////////////////
1455+
1456+
bool
1457+
MCExtensionInitialize(void)
1458+
{
1459+
return MCScriptForEachBuiltinModule([](void *p_context, MCScriptModuleRef p_module) {
1460+
if (MCScriptIsModuleALibrary(p_module) ||
1461+
MCScriptIsModuleAWidget(p_module))
1462+
{
1463+
return MCEngineAddExtensionFromModule(p_module);
1464+
}
1465+
1466+
return true;
1467+
}, nullptr);
1468+
}
1469+
1470+
void
1471+
MCExtensionFinalize(void)
1472+
{
1473+
while(MCextensions != nullptr)
1474+
{
1475+
/* Unlink the extension from the global list */
1476+
MCLoadedExtension *t_ext = MCextensions;
1477+
MCextensions = MCextensions->next;
1478+
1479+
/* Free the extensions */
1480+
__MCEngineFreeExtension(t_ext);
1481+
}
1482+
}
1483+
1484+
14381485
////////////////////////////////////////////////////////////////////////////////

engine/src/exec.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5594,6 +5594,9 @@ void MCNFCExecDisableNFCDispatch(MCExecContext& ctxt);
55945594

55955595
////////////////////////////////////////////////////////////////////////////////
55965596

5597+
bool MCExtensionInitialize(void);
5598+
void MCExtensionFinalize(void);
5599+
55975600
bool MCExtensionConvertToScriptType(MCExecContext& ctxt, MCValueRef& x_value);
55985601
bool MCExtensionConvertFromScriptType(MCExecContext& ctxt, MCTypeInfoRef p_type, MCValueRef& x_value);
55995602

engine/src/globals.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,6 +1238,13 @@ bool X_open(int argc, MCStringRef argv[], MCStringRef envp[])
12381238

12391239
MCwidgeteventmanager = new (nothrow) MCWidgetEventManager;
12401240

1241+
/* Now that the script engine state has been initialized, we can load all
1242+
* builtin extensions. */
1243+
if (!MCExtensionInitialize())
1244+
{
1245+
return false;
1246+
}
1247+
12411248
// MW-2009-07-02: Clear the result as a startup failure will be indicated
12421249
// there.
12431250
MCresult -> clear();
@@ -1249,6 +1256,9 @@ bool X_open(int argc, MCStringRef argv[], MCStringRef envp[])
12491256

12501257
int X_close(void)
12511258
{
1259+
/* Finalize all builtin extensions */
1260+
MCExtensionFinalize();
1261+
12521262
// MW-2008-01-18: [[ Bug 5711 ]] Make sure we disable the backdrop here otherwise we
12531263
// get crashiness on Windows due to hiding the backdrop calling WindowProc which
12541264
// attempts to access stacks that have been deleted...

libscript/include/libscript/script.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,15 @@ typedef MCScriptInstance *MCScriptInstanceRef;
3939

4040
////////////////////////////////////////////////////////////////////////////////
4141

42+
typedef bool (*MCScriptForEachBuiltinModuleCallback)(void *p_context, MCScriptModuleRef p_module);
43+
4244
typedef bool (*MCScriptLoadLibraryCallback)(MCScriptModuleRef module, MCStringRef name, MCSLibraryRef& r_library);
4345

4446
bool MCScriptInitialize(void);
4547
void MCScriptFinalize(void);
4648

49+
bool MCScriptForEachBuiltinModule(MCScriptForEachBuiltinModuleCallback p_callback, void *p_context);
50+
4751
void MCScriptSetLoadLibraryCallback(MCScriptLoadLibraryCallback callback);
4852

4953
////////////////////////////////////////////////////////////////////////////////

libscript/src/script-object.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,21 @@ bool MCScriptLoadLibrary(MCScriptModuleRef p_module, MCStringRef p_name, MCSLibr
338338
r_library);
339339
}
340340

341+
bool
342+
MCScriptForEachBuiltinModule(MCScriptForEachBuiltinModuleCallback p_callback,
343+
void *p_context)
344+
{
345+
for(MCBuiltinModule *t_module = s_builtin_modules; t_module != nullptr; t_module = t_module -> next)
346+
{
347+
if (!p_callback(p_context, t_module->handle))
348+
{
349+
return false;
350+
}
351+
}
352+
353+
return true;
354+
}
355+
341356
MCSLibraryRef MCScriptGetLibrary(void)
342357
{
343358
return s_libscript_library;

0 commit comments

Comments
 (0)