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

attach(ifun, info)[source]

Compiles the body of ifun and attaches it to info.

create_function(ifun)[source]

A function table made at run time, without a step.

datatype(fullname)[source]
materialize(iobj)[source]
materializeEx(iobj)[source]
symbol(fullname)[source]

The info table of a function or constructor. A function of this module not yet materialized gets its table now; the loader attaches its body when it reaches it.

tag(fullname)[source]
trap(info)[source]

Gives info the trap step and records the module as pending its compile on first use (see the module docstring).

class curry.backends.cxx.materialize.Pending(interp, moduleobj)[source]

Bases: object

A 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. currypath is 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 code text: 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. currypath is 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 info and 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 moduleobj waits for its compile on first use.

curry.backends.cxx.materialize.is_translation(interp, imodule)[source]

Tells whether the ICurry object imodule is 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.materialize(interp, iobj, moduleobj)[source]
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.

curry.backends.cxx.materialize.process_file(imodule)[source]

The generated file of the module in the directory of the process (tiered._tmpdir), in the layout of a product directory, which the toolchain reads the module name from. The product cache leaves the directory out (_productcache.excluded).

curry.backends.cxx.materialize.product_file(imodule)[source]

The generated file of the module in the product directory beside its source, as the plan writes it, when the module has a source file and the directory can be written; else None.