# HG changeset patch # User Paul Boddie # Date 1386457551 -3600 # Node ID 1d18a182148bb042b4e087ad30bbc063f793d529 # Parent d148464ebb37944496e94463beebd8744fea69cb Removed __context__ from argument lists since it will be transferred separately. diff -r d148464ebb37 -r 1d18a182148b docs/invocation.txt --- a/docs/invocation.txt Wed Dec 04 16:17:20 2013 +0100 +++ b/docs/invocation.txt Sun Dec 08 00:05:51 2013 +0100 @@ -53,6 +53,19 @@ These cases require additional structures to be created, potentially at run-time. +Invocations and argument lists: + + General procedure: + + 1. Load target. + 2. Put target in list (if appropriate). + 3. Put context in list (if appropriate). + 4. Put arguments in list. + 5. Jump to target. + + The target is needed for dynamic functions and methods, but is external to + any notion of arguments or locals. + Methods vs. functions: f(obj, 1, 2) # f known as function at compile-time: @@ -196,21 +209,13 @@ def f(x, y=nonconst): ... - Defines instance with method: - - def (, x, y=nonconst): - ... - - def f(, x, y=nonconst): - ... + Defines object referencing function: - Where default is attribute #1. - - f(obj) # f not known at compile-time + def (x, y=nonconst): # references lambda x, ... + # Obtain nonconst from for y, if necessary - f -> f - -> load context for argument #1 (f, since an instance is referenced) - obj -> argument #2 + def (x, y=nonconst): # references f + # Obtain nonconst from for y, if necessary Dynamic default information and methods: @@ -218,11 +223,14 @@ def f(self, y=nonconst): ... - Defines additional context for the method: + Defines additional state for the method: class C: - def f(, self, y=nonconst): - ... + def (self, y=nonconst): # references C.f + # Obtain nonconst from for y, if necessary + + Non-constant information is only likely to be introduced to method defaults + within loops or if classes are permitted within functions. Functions as methods: diff -r d148464ebb37 -r 1d18a182148b docs/syspython.txt --- a/docs/syspython.txt Wed Dec 04 16:17:20 2013 +0100 +++ b/docs/syspython.txt Sun Dec 08 00:05:51 2013 +0100 @@ -33,21 +33,17 @@ applystaticmethod(fn, obj, ...) # specific invocation of a method via a class applymethod(fn, obj, ...) # specific invocation of a method via self -Where dynamic functions are to be invoked, the context providing the defaults -needs to be supplied to the function or method, but this can be done using the -above special functions as follows: - - applyclass(cls, __context__, ...) - applyfunction(fn, __context__, ...) - applystaticmethod(fn, __context__, obj, ...) - applymethod(fn, __context__, obj, ...) +Where dynamic functions are to be invoked, the object providing the defaults +needs to be supplied to the function or method, but this should be done by the +invocation mechanism implemented on the target architecture, exposing only a +special __context__ local name providing access to the defaults. Where optimisation possibilities cannot be identified in advance, the apply function must deal with the following aspects of invocation: + * Whether a dynamic function is being invoked, thus requiring an object for + access to defaults * Whether a context argument is required - * Whether a dynamic function is being invoked, thus requiring a context for - access to defaults * Whether an appropriate number of arguments have been provided Low-Level Code @@ -186,17 +182,17 @@ This is represented as follows: def outer(x): - def inner(__context__, y, z=x): - localnames(__context__, y, z) + def inner(y, z=x): + localnames(y, z, __context__) ... storelocal(inner, makedynamic(static(module.outer.inner), x)) return inner The special makedynamic invocation creates an object referring to the function and incorporating any specified defaults as attributes of that object. The -function itself uses a special __context__ parameter that acts somewhat like -the self parameter in methods: when invoked, the __context__ provides access -to any default information that needs to be transferred to the local +function itself will use a special __context__ local that acts somewhat like +the self parameter in methods: in the invoked function, __context__ provides +access to any default information that needs to be transferred to the local namespace. Function defaults that do not require a dynamic function are initialised using diff -r d148464ebb37 -r 1d18a182148b micropython/data.py --- a/micropython/data.py Wed Dec 04 16:17:20 2013 +0100 +++ b/micropython/data.py Sun Dec 08 00:05:51 2013 +0100 @@ -1256,12 +1256,9 @@ def _make_dynamic(self): - "Where functions have dynamic defaults, add a context argument." + "Where functions have dynamic defaults, add a context local." - name = "__context__" - self.argnames.insert(0, name) - self.positional_names.insert(0, name) - self.set(name, make_instance()) + self.set("__context__", make_instance()) # Namespace-related methods. @@ -1362,7 +1359,7 @@ if self.finalised: return - # Defaults. + # Defaults are positioned in the function structure. for i, default in enumerate(self.default_attrs): default.position = i @@ -1376,7 +1373,8 @@ else: nparams = 0 - # Locals (and tuple parameter names). + # Locals (and tuple parameter names) are positioned in the current stack + # frame. i = None for i, attr in enumerate(self.locals().values()):