1.1 --- a/micropython/__init__.py Sat Jun 30 00:15:09 2012 +0200
1.2 +++ b/micropython/__init__.py Sat Jun 30 17:06:37 2012 +0200
1.3 @@ -254,8 +254,9 @@
1.4 # Get the raw version for the architecture.
1.5
1.6 if arch_item is not None:
1.7 + arch_item.finalise_location(with_builtins)
1.8 self.raw_code += arch_item.as_raw(objtable, paramtable, with_builtins)
1.9 - arch_item.finalise_location(with_builtins)
1.10 + arch_item.finalise_body_location(with_builtins)
1.11 else:
1.12 self.raw_code.append(item)
1.13
1.14 @@ -266,8 +267,6 @@
1.15 if not with_builtins and module.name in ("__builtins__", "native"):
1.16 continue
1.17
1.18 - module.code_location = module.blocks[0].location
1.19 -
1.20 self.code_location = self.importer.modules["__main__"].code_location
1.21 return self.raw_code
1.22
1.23 @@ -415,6 +414,10 @@
1.24 self.modules_ordered = []
1.25 self.loading = set()
1.26
1.27 + # Importers responsible for initially importing modules.
1.28 +
1.29 + self.importers = {}
1.30 +
1.31 # Constant records.
1.32
1.33 self.constant_values = {}
1.34 @@ -948,12 +951,16 @@
1.35 else:
1.36 return None
1.37
1.38 - def load(self, name, return_leaf=0):
1.39 + def load(self, name, return_leaf=0, importer=None):
1.40
1.41 """
1.42 Load the module or package with the given 'name'. Return an object
1.43 referencing the loaded module or package, or None if no such module or
1.44 package exists.
1.45 +
1.46 + If the given 'importer' is specified, it will be associated with the
1.47 + imported module if it is responsible for importing the module for the
1.48 + first time.
1.49 """
1.50
1.51 if return_leaf:
1.52 @@ -961,7 +968,7 @@
1.53 else:
1.54 name_for_return = name.split(".")[0]
1.55
1.56 - if self.modules.has_key(name) and self.modules[name].loaded:
1.57 + if self.modules.has_key(name):
1.58 #print >>sys.stderr, "Cached (%s)" % name
1.59 return self.modules[name_for_return]
1.60
1.61 @@ -982,7 +989,7 @@
1.62 # Either acquire a reference to an already-imported module, or load the
1.63 # module from a file.
1.64
1.65 - top = module = self.load_from_file(filename, path[0])
1.66 + top = module = self.load_from_file(filename, path[0], importer)
1.67
1.68 # For hierarchical names, traverse each path component...
1.69
1.70 @@ -1010,7 +1017,7 @@
1.71
1.72 # Either reference an imported module or load one from a file.
1.73
1.74 - submodule = self.load_from_file(filename, module_name)
1.75 + submodule = self.load_from_file(filename, module_name, importer)
1.76
1.77 if d:
1.78 self.add_submodules(d, module)
1.79 @@ -1032,10 +1039,14 @@
1.80 else:
1.81 return top
1.82
1.83 - def load_from_file(self, name, module_name=None):
1.84 + def load_from_file(self, name, module_name=None, importer=None):
1.85
1.86 """
1.87 Load the module with the given 'name' (which may be a full module path).
1.88 +
1.89 + If the given 'importer' is specified, it will be associated with the
1.90 + imported module if it is responsible for importing the module for the
1.91 + first time.
1.92 """
1.93
1.94 if module_name is None:
1.95 @@ -1052,6 +1063,13 @@
1.96 self.loading.remove(module)
1.97 module.loaded = 1
1.98
1.99 + # Record each module as imported by any importer.
1.100 +
1.101 + if importer:
1.102 + if not self.importers.has_key(importer):
1.103 + self.importers[importer] = []
1.104 + self.importers[importer].append(module)
1.105 +
1.106 # Record the module.
1.107
1.108 self.use_object(module.full_name())
2.1 --- a/micropython/ast.py Sat Jun 30 00:15:09 2012 +0200
2.2 +++ b/micropython/ast.py Sat Jun 30 17:06:37 2012 +0200
2.3 @@ -106,7 +106,12 @@
2.4 if self.module.name == "__main__":
2.5 self.set_block(handler_block)
2.6 self.new_op(PopHandler(1))
2.7 - self.new_op(Return())
2.8 + else:
2.9 + self.new_op(DropFrame())
2.10 +
2.11 + # All modules return if invoked.
2.12 +
2.13 + self.new_op(Return())
2.14
2.15 self.drop_exception_unit()
2.16 self.unit.temp_usage = self.max_temp_position + 1
2.17 @@ -155,7 +160,7 @@
2.18
2.19 self.new_op(LoadFunction(init_method))
2.20 self.new_op(LoadCallable())
2.21 - self.new_op(JumpInFrame())
2.22 + self.new_op(JumpWithFrame())
2.23
2.24 # Store the object as the result.
2.25
2.26 @@ -614,7 +619,20 @@
2.27
2.28 def visitDecorators(self, node): raise TranslationNotImplementedError("Decorators")
2.29
2.30 - def visitFrom(self, node): pass
2.31 + def visitFrom(self, node):
2.32 +
2.33 + """
2.34 + Although imported code already resides in any generated image, the
2.35 + code must be invoked.
2.36 + """
2.37 +
2.38 + modules = self.importer.importers.get(node)
2.39 + if modules:
2.40 + for module in modules:
2.41 + self.new_op(MakeFrame(0))
2.42 + self.new_op(LoadConst(module))
2.43 + self.new_op(LoadCallable())
2.44 + self.new_op(JumpWithFrame())
2.45
2.46 def visitFunction(self, node):
2.47 if not used_by_unit(node):
2.48 @@ -641,7 +659,7 @@
2.49
2.50 def visitGlobal(self, node): pass
2.51
2.52 - def visitImport(self, node): pass
2.53 + visitImport = visitFrom
2.54
2.55 def visitKeyword(self, node): pass
2.56
3.1 --- a/micropython/inspect.py Sat Jun 30 00:15:09 2012 +0200
3.2 +++ b/micropython/inspect.py Sat Jun 30 17:06:37 2012 +0200
3.3 @@ -991,7 +991,7 @@
3.4 self.resume_broken_branches()
3.5
3.6 def visitFrom(self, node):
3.7 - module = self.importer.load(node.modname, 1)
3.8 + module = self.importer.load(node.modname, 1, importer=node)
3.9 if module and not module.loaded:
3.10 print >>sys.stderr, "Warning: a circular import of %s is being attempted in %s" % (node.modname, self.full_name())
3.11
3.12 @@ -1005,7 +1005,7 @@
3.13 # Missing names may refer to submodules.
3.14
3.15 if not module.has_key(name):
3.16 - submodule = self.importer.load(node.modname + "." + name, 1)
3.17 + submodule = self.importer.load(node.modname + "." + name, 1, importer=node)
3.18 if submodule:
3.19 if not submodule.loaded:
3.20 print >>sys.stderr, "Warning: a circular import of %s.%s is being attempted in %s" % (
3.21 @@ -1020,7 +1020,7 @@
3.22 self.store(alias or name, attr)
3.23 self.use_specific_attribute(module.full_name(), name)
3.24 if isinstance(attr.get_value(), Module) and not attr.get_value().loaded:
3.25 - self.importer.load(attr.get_value().name)
3.26 + self.importer.load(attr.get_value().name, importer=node)
3.27 continue
3.28
3.29 # Support the import of names from missing modules.
3.30 @@ -1034,7 +1034,7 @@
3.31 self.store(n, attr)
3.32 self.use_specific_attribute(module.full_name(), n)
3.33 if isinstance(attr.get_value(), Module) and not attr.get_value().loaded:
3.34 - self.importer.load(attr.get_value().name)
3.35 + self.importer.load(attr.get_value().name, importer=node)
3.36
3.37 def visitFunction(self, node):
3.38 return self._visitFunction(node, node.name)
3.39 @@ -1106,10 +1106,10 @@
3.40 def visitImport(self, node):
3.41 for name, alias in node.names:
3.42 if alias is not None:
3.43 - module = self.importer.load(name, 1) or UnresolvedName(None, name, self)
3.44 + module = self.importer.load(name, 1, importer=node) or UnresolvedName(None, name, self)
3.45 self.store(alias, module)
3.46 else:
3.47 - module = self.importer.load(name) or UnresolvedName(None, name.split(".")[0], self)
3.48 + module = self.importer.load(name, importer=node) or UnresolvedName(None, name.split(".")[0], self)
3.49 self.store(name.split(".")[0], module)
3.50
3.51 visitInvert = _visitUnary
4.1 --- a/micropython/raw.py Sat Jun 30 00:15:09 2012 +0200
4.2 +++ b/micropython/raw.py Sat Jun 30 17:06:37 2012 +0200
4.3 @@ -3,7 +3,7 @@
4.4 """
4.5 Classes used to help with the generation of raw image data.
4.6
4.7 -Copyright (C) 2009, 2010, 2011 Paul Boddie <paul@boddie.org.uk>
4.8 +Copyright (C) 2009, 2010, 2011, 2012 Paul Boddie <paul@boddie.org.uk>
4.9
4.10 This program is free software; you can redistribute it and/or modify it under
4.11 the terms of the GNU General Public License as published by the Free Software
4.12 @@ -33,6 +33,9 @@
4.13 def finalise_location(self, with_builtins):
4.14 pass
4.15
4.16 + def finalise_body_location(self, with_builtins):
4.17 + pass
4.18 +
4.19 def is_generated(self, with_builtins):
4.20 return with_builtins or self.item.module.name not in ("__builtins__", "native") or self.item.astnode.doc is not None
4.21
5.1 --- a/micropython/rsvp.py Sat Jun 30 00:15:09 2012 +0200
5.2 +++ b/micropython/rsvp.py Sat Jun 30 17:06:37 2012 +0200
5.3 @@ -3,7 +3,7 @@
5.4 """
5.5 RSVP instruction and serialisation classes.
5.6
5.7 -Copyright (C) 2007, 2008, 2009, 2010, 2011 Paul Boddie <paul@boddie.org.uk>
5.8 +Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 Paul Boddie <paul@boddie.org.uk>
5.9
5.10 This program is free software; you can redistribute it and/or modify it under
5.11 the terms of the GNU General Public License as published by the Free Software
5.12 @@ -87,7 +87,7 @@
5.13
5.14 return RSVPObject.set_location(self, location + 1, objtable, with_builtins)
5.15
5.16 - def finalise_location(self, with_builtins):
5.17 + def finalise_body_location(self, with_builtins):
5.18 self._finalise_location(with_builtins)
5.19
5.20 def as_raw(self, objtable, paramtable, with_builtins):
5.21 @@ -235,7 +235,7 @@
5.22
5.23 return location
5.24
5.25 - def finalise_location(self, with_builtins):
5.26 + def finalise_body_location(self, with_builtins):
5.27 self._finalise_location(with_builtins)
5.28
5.29 def as_raw(self, objtable, paramtable, with_builtins):
5.30 @@ -256,13 +256,18 @@
5.31
5.32 "A wrapper for modules."
5.33
5.34 + def finalise_location(self, with_builtins):
5.35 + item = self.item
5.36 + if item.blocks:
5.37 + item.code_location = item.blocks[0].location
5.38 +
5.39 def as_raw(self, objtable, paramtable, with_builtins):
5.40 item = self.item
5.41 return [
5.42 DataObject(
5.43 objtable.as_list().get_code(item.full_name()),
5.44 None, # modules treated like classes
5.45 - None,
5.46 + item.code_location,
5.47 item.full_name(),
5.48 len(item.module_attributes()) + 1 # size
5.49 )
5.50 @@ -409,7 +414,7 @@
5.51
5.52 class TargetInstruction(Instruction):
5.53
5.54 - "An instruction loading the address of an invocation target."
5.55 + "An instruction loading the address of a direct invocation target."
5.56
5.57 def format_operand(self):
5.58 return Instruction.format_operand(self) + ["name=%r" % name(self.attr)]
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/tests/class_init_code.py Sat Jun 30 17:06:37 2012 +0200
6.3 @@ -0,0 +1,8 @@
6.4 +#!/usr/bin/env python
6.5 +
6.6 +class C:
6.7 + x = 1 + 2
6.8 +
6.9 +result_3 = C.x
6.10 +
6.11 +# vim: tabstop=4 expandtab shiftwidth=4
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/tests/initialised/__init__.py Sat Jun 30 17:06:37 2012 +0200
7.3 @@ -0,0 +1,5 @@
7.4 +#!/usr/bin/env python
7.5 +
7.6 +x = 100 + 20 + 3
7.7 +
7.8 +# vim: tabstop=4 expandtab shiftwidth=4
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/tests/module_init.py Sat Jun 30 17:06:37 2012 +0200
8.3 @@ -0,0 +1,7 @@
8.4 +#!/usr/bin/env python
8.5 +
8.6 +import initialised
8.7 +
8.8 +result_123 = initialised.x
8.9 +
8.10 +# vim: tabstop=4 expandtab shiftwidth=4