py/objmodule: Add a table of built-in modules with delegation.
This replaces the previous QSTR_null entry in the globals dict which could leak out to Python (e.g. via iteration of mod.__dict__) and could lead to crashes. It results in smaller code size at the expense of turning a lookup into a loop, but the list it is looping over likely only contains one or two elements. To allow a module to register its custom attr function it can use the new `MP_REGISTER_MODULE_DELEGATION` macro. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This commit is contained in:
@@ -22,11 +22,16 @@ import io
|
||||
import argparse
|
||||
|
||||
|
||||
pattern = re.compile(
|
||||
register_pattern = re.compile(
|
||||
r"\s*(MP_REGISTER_MODULE|MP_REGISTER_EXTENSIBLE_MODULE)\(MP_QSTR_(.*?),\s*(.*?)\);",
|
||||
flags=re.DOTALL,
|
||||
)
|
||||
|
||||
delegation_pattern = re.compile(
|
||||
r"\s*(?:MP_REGISTER_MODULE_DELEGATION)\((.*?),\s*(.*?)\);",
|
||||
flags=re.DOTALL,
|
||||
)
|
||||
|
||||
|
||||
def find_module_registrations(filename):
|
||||
"""Find any MP_REGISTER_MODULE definitions in the provided file.
|
||||
@@ -37,7 +42,8 @@ def find_module_registrations(filename):
|
||||
global pattern
|
||||
|
||||
with io.open(filename, encoding="utf-8") as c_file_obj:
|
||||
return set(re.findall(pattern, c_file_obj.read()))
|
||||
c = c_file_obj.read()
|
||||
return set(re.findall(register_pattern, c)), set(re.findall(delegation_pattern, c))
|
||||
|
||||
|
||||
def generate_module_table_header(modules):
|
||||
@@ -50,7 +56,6 @@ def generate_module_table_header(modules):
|
||||
# Print header file for all external modules.
|
||||
mod_defs = set()
|
||||
extensible_mod_defs = set()
|
||||
print("// Automatically generated by makemoduledefs.py.\n")
|
||||
for macro_name, module_name, obj_module in modules:
|
||||
mod_def = "MODULE_DEF_{}".format(module_name.upper())
|
||||
if macro_name == "MP_REGISTER_MODULE":
|
||||
@@ -97,13 +102,27 @@ def generate_module_table_header(modules):
|
||||
print("// MICROPY_REGISTERED_EXTENSIBLE_MODULES")
|
||||
|
||||
|
||||
def generate_module_delegations(delegations):
|
||||
print("\n#define MICROPY_MODULE_DELEGATIONS \\")
|
||||
for obj_module, fun_name in delegations:
|
||||
print(
|
||||
" {{ MP_ROM_PTR(&{obj_module}), {fun_name} }},".format(
|
||||
obj_module=obj_module, fun_name=fun_name
|
||||
)
|
||||
)
|
||||
print("// MICROPY_MODULE_DELEGATIONS")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("file", nargs=1, help="file with MP_REGISTER_MODULE definitions")
|
||||
args = parser.parse_args()
|
||||
|
||||
modules = find_module_registrations(args.file[0])
|
||||
print("// Automatically generated by makemoduledefs.py.\n")
|
||||
|
||||
modules, delegations = find_module_registrations(args.file[0])
|
||||
generate_module_table_header(sorted(modules))
|
||||
generate_module_delegations(sorted(delegations))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user