Skip to content

Commit c1d63ef

Browse files
committed
[[ Bug 14514 ]] Ensure that chained imports resolve properly.
It is now possible for an import definition to reference an external definition in another module. This means that resolution of a definition needs to be changed. This has been implemented by ensuring a module is valid before importing from it, and then using the resolved imports in that module, when resolving an external definition whilst the using module is being made usable.
1 parent 6d7d20e commit c1d63ef

File tree

3 files changed

+25
-10
lines changed

3 files changed

+25
-10
lines changed

libscript/src/script-instance.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -657,8 +657,8 @@ static inline void MCScriptResolveDefinitionInFrame(MCScriptFrame *p_frame, uind
657657
MCScriptImportedDefinition *t_import_def;
658658
t_import_def = &t_instance -> module -> imported_definitions[t_ext_def -> index];
659659

660-
t_instance = t_instance -> module -> dependencies[t_import_def -> module] . instance;
661-
t_definition = t_import_def -> definition;
660+
t_instance = t_import_def -> resolved_module -> shared_instance;
661+
t_definition = t_import_def -> resolved_definition;
662662
}
663663

664664
r_instance = t_instance;

libscript/src/script-module.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,11 @@ bool MCScriptEnsureModuleIsUsable(MCScriptModuleRef self)
461461
if (t_module -> module_kind == kMCScriptModuleKindWidget)
462462
return false;
463463

464+
// A used module must be usable - do this before resolving imports so
465+
// chained imports work.
466+
if (!MCScriptEnsureModuleIsUsable(t_module))
467+
return false;
468+
464469
// Check all the imported definitions from the module, and compute indicies.
465470
for(uindex_t t_import = 0; t_import < self -> imported_definition_count; t_import++)
466471
{
@@ -473,6 +478,17 @@ bool MCScriptEnsureModuleIsUsable(MCScriptModuleRef self)
473478
if (!MCScriptLookupDefinitionInModule(t_module, t_import_def -> name, t_def))
474479
return false;
475480

481+
MCScriptModuleRef t_mod;
482+
if (t_def -> kind == kMCScriptDefinitionKindExternal)
483+
{
484+
MCScriptExternalDefinition *t_ext_def;
485+
t_ext_def = static_cast<MCScriptExternalDefinition *>(t_def);
486+
t_mod = t_module -> imported_definitions[t_ext_def -> index] . resolved_module;
487+
t_def = t_module -> imported_definitions[t_ext_def -> index] . resolved_definition;
488+
}
489+
else
490+
t_mod = t_module;
491+
476492
if (t_def -> kind != t_import_def -> kind)
477493
{
478494
if (t_import_def -> kind != kMCScriptDefinitionKindHandler ||
@@ -482,13 +498,10 @@ bool MCScriptEnsureModuleIsUsable(MCScriptModuleRef self)
482498

483499
// Check that signatures match.
484500

485-
t_import_def -> definition = t_def;
501+
t_import_def -> resolved_definition = t_def;
502+
t_import_def -> resolved_module = t_mod;
486503
}
487504

488-
// A used module must be usable.
489-
if (!MCScriptEnsureModuleIsUsable(t_module))
490-
return false;
491-
492505
// Now create the instance we need.
493506
if (!MCScriptCreateInstanceOfModule(t_module, self -> dependencies[i] . instance))
494507
return false;
@@ -567,8 +580,8 @@ bool MCScriptEnsureModuleIsUsable(MCScriptModuleRef self)
567580
t_import = &self -> imported_definitions[t_ext_def -> index];
568581

569582
MCScriptModuleRef t_module;
570-
t_module = self -> dependencies[t_import -> module] . instance -> module;
571-
t_typeinfo = t_module -> types[static_cast<MCScriptTypeDefinition *>(t_import -> definition) -> type] -> typeinfo;
583+
t_module = t_import -> resolved_module;
584+
t_typeinfo = t_module -> types[static_cast<MCScriptTypeDefinition *>(t_import -> resolved_definition) -> type] -> typeinfo;
572585
}
573586
else
574587
return false;

libscript/src/script-private.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,10 @@ struct MCScriptImportedDefinition
210210
MCScriptDefinitionKind kind;
211211
MCNameRef name;
212212

213+
// The module the definition resides in.
214+
MCScriptModuleRef resolved_module;
213215
// The resolved definition - not pickled
214-
MCScriptDefinition *definition;
216+
MCScriptDefinition *resolved_definition;
215217
};
216218

217219
struct MCScriptPosition

0 commit comments

Comments
 (0)