curry.backends.cxx.materialize module
Code for converting the intermediate representation to executable code.
A module loaded from its compiled object carries its info tables and data
types in its metadata (cxx.material; see loader.py), and the materializer
returns them. A module imported from its ICurry gets info tables and data
types made at run time (Module::create_infotable, Module::create_type). Under
the interpreter flag interpret the functions of such a module are
interpreted: the materializer compiles the body of each function into the
bytecode of the runtime (bytecode.py) and attaches it to the info table
(cyrt/icurry.hpp).
With the flag ‘off’ the plan of the toolchain compiles every module it
loads, but a module imported from an ICurry object (curry.import_(imodule))
never goes through the plan, and its functions got no step: the first
evaluation of one crashed the process (issue #102). Now such a function
gets the trap step of the runtime (cyrt/module.hpp), and the module compiles
on its first use: the trap calls first_use, which generates the C++ of
the ICurry object in hand and compiles it with the step of the toolchain
that sprite-make –so runs (Cpp2So), loads the object over the shim of the
module (tiered.py) and swaps the steps (cyrt.tiered_adopt); then the step
runs compiled. So a user who asked for compiled code gets it, and the
plan’s own import of an ICurry object, which only generates code
(Json2TargetSource), compiles nothing.
Where the products go (compile_pending). The products beside a source
and the entries of the product cache belong to the translation of the
texts on disk: a later import of the module by name loads them. So the
C++ goes beside the source, and the object into the product cache, only
when the object in hand is that translation (is_translation: the JSON
beside the source, read again and taken through the merge and the passes
of an import, has the structure of the object). There a current object
whose generated file has the same text is adopted without a compile, and
the product cache is asked before the compiler, as the plan does. A
transformed object (an experiment of the optimizer, a test), a module
without a source file, and every module of a process whose inline budget
is not the environment’s (tiered._foreign_flags; issue #116) compile into a
directory of the process (tiered._tmpdir), which the product cache leaves
out. A function that still has no code when it is called raises
EvaluationError that names the function and its module and the reason: the
compile failed, or COMPILE_ON_FIRST_USE is False (the hook of the tests).
The body of a function may name a function of its module that the loader has not reached yet. The resolver makes the info table of such a function on demand; the loader finds it and attaches the body when it reaches it.
- class curry.backends.cxx.materialize.Materializer(interp, moduleobj)[source]
Bases:
object
- class curry.backends.cxx.materialize.Pending(interp, moduleobj)[source]
Bases:
objectA module imported from an ICurry object under interpret:off: its function tables carry the trap step until its first use compiles it. The module and its interpreter are held weakly; a module that was unloaded compiles nothing.
currypathis the search path of the imports of the module (module_loaded), which the compile of the module needs for its imports.- property name
- curry.backends.cxx.materialize.compile_pending(entry)[source]
Compiles a pending module and swaps its steps: the compile on first use. The pending imports of the module compile first, because an object names the objects of its imports. The tables of the module are kept for the process and its shim is linked and loaded (tiered.py), so that the object binds its tables to the tables the nodes and the Python objects hold. The C++ of the ICurry object in hand goes beside the source when the object is the translation on disk (is_translation) under the optimizer flags of the environment (tiered._foreign_flags), else into a directory of the process (see the module docstring); a current object beside the source is adopted as it is (current_object), else Cpp2So compiles the file, as sprite-make –so does; the runtime loads the object and swaps the steps (cyrt.tiered_adopt). Raises CompileError when a step fails; the module then stays trapped.
- curry.backends.cxx.materialize.current_object(cpp2so, cppfile, text, currypath)[source]
The current object of the module beside
cppfile, the generated file beside the source, for the generated codetext: the object there, when its generated file has the text and the object is not stale (Cpp2So.is_stale: its stamp and the objects of its imports); else the object the product cache places for the texts on disk (Cpp2So.restore), when the generated file it places has the text. None when there is neither: the module compiles.currypathis the search path of the imports of the module (module_loaded).
- curry.backends.cxx.materialize.first_use(info)[source]
The hook of the trap step (cyrt.set_trap_hook): compiles the module of the table
infoand swaps its steps, so that the trap runs the compiled step. Returns None when the table has its code now, else the reason it has not, which the error of the trap names. Runs inside a rewrite step, on the thread that evaluates.
- curry.backends.cxx.materialize.is_pending(moduleobj)[source]
Tells whether
moduleobjwaits for its compile on first use.
- curry.backends.cxx.materialize.is_translation(interp, imodule)[source]
Tells whether the ICurry object
imoduleis the translation of its source as it stands on disk. The JSON beside the source is read again (the file, not the parsed cache) and taken through the merge and the passes of an import; the object is the translation when the two have one structure (icurry.json.dumps, which leaves the metadata out). False for an object without a source file or without a JSON beside it. The products beside a source and the product cache belong to that translation, so the products of any other object stay out of both.
- curry.backends.cxx.materialize.module_loaded(interp, moduleobj, currypath)[source]
Called when the import of a module ends (IBackend.module_loaded). Records the search path of the import for the compile on first use of a pending module.